appstore-connect-sdk 1.2.0 → 1.3.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/README.md +1 -1
- package/dist/cjs/main.js +175 -8
- package/dist/cjs/main.js.map +2 -2
- package/dist/main.js +175 -8
- package/dist/main.js.map +2 -2
- package/dist/types/auth.d.ts +1 -1
- package/dist/types/main.d.ts +40 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -86,7 +86,7 @@ import { AppStoreConnectAPI } from "appstore-connect-sdk";
|
|
|
86
86
|
import {
|
|
87
87
|
AppsApi,
|
|
88
88
|
AppEventLocalizationsApi,
|
|
89
|
-
} from "appstore-connect-sdk/
|
|
89
|
+
} from "appstore-connect-sdk/openapi";
|
|
90
90
|
|
|
91
91
|
const client = new AppStoreConnectAPI({
|
|
92
92
|
issuerId: "<YOUR ISSUER ID>",
|
package/dist/cjs/main.js
CHANGED
|
@@ -83,6 +83,135 @@ var Configuration = class {
|
|
|
83
83
|
}
|
|
84
84
|
};
|
|
85
85
|
var DefaultConfig = new Configuration();
|
|
86
|
+
var BaseAPI = class {
|
|
87
|
+
constructor(configuration = DefaultConfig) {
|
|
88
|
+
this.configuration = configuration;
|
|
89
|
+
this.fetchApi = async (url, init) => {
|
|
90
|
+
let fetchParams = { url, init };
|
|
91
|
+
for (const middleware of this.middleware) {
|
|
92
|
+
if (middleware.pre) {
|
|
93
|
+
fetchParams = await middleware.pre({
|
|
94
|
+
fetch: this.fetchApi,
|
|
95
|
+
...fetchParams
|
|
96
|
+
}) || fetchParams;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
let response = void 0;
|
|
100
|
+
try {
|
|
101
|
+
response = await (this.configuration.fetchApi || fetch)(fetchParams.url, fetchParams.init);
|
|
102
|
+
} catch (e) {
|
|
103
|
+
for (const middleware of this.middleware) {
|
|
104
|
+
if (middleware.onError) {
|
|
105
|
+
response = await middleware.onError({
|
|
106
|
+
fetch: this.fetchApi,
|
|
107
|
+
url: fetchParams.url,
|
|
108
|
+
init: fetchParams.init,
|
|
109
|
+
error: e,
|
|
110
|
+
response: response ? response.clone() : void 0
|
|
111
|
+
}) || response;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
if (response === void 0) {
|
|
115
|
+
if (e instanceof Error) {
|
|
116
|
+
throw new FetchError(e, "The request failed and the interceptors did not return an alternative response");
|
|
117
|
+
} else {
|
|
118
|
+
throw e;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
for (const middleware of this.middleware) {
|
|
123
|
+
if (middleware.post) {
|
|
124
|
+
response = await middleware.post({
|
|
125
|
+
fetch: this.fetchApi,
|
|
126
|
+
url: fetchParams.url,
|
|
127
|
+
init: fetchParams.init,
|
|
128
|
+
response: response.clone()
|
|
129
|
+
}) || response;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return response;
|
|
133
|
+
};
|
|
134
|
+
this.middleware = configuration.middleware;
|
|
135
|
+
}
|
|
136
|
+
withMiddleware(...middlewares) {
|
|
137
|
+
const next = this.clone();
|
|
138
|
+
next.middleware = next.middleware.concat(...middlewares);
|
|
139
|
+
return next;
|
|
140
|
+
}
|
|
141
|
+
withPreMiddleware(...preMiddlewares) {
|
|
142
|
+
const middlewares = preMiddlewares.map((pre) => ({ pre }));
|
|
143
|
+
return this.withMiddleware(...middlewares);
|
|
144
|
+
}
|
|
145
|
+
withPostMiddleware(...postMiddlewares) {
|
|
146
|
+
const middlewares = postMiddlewares.map((post) => ({ post }));
|
|
147
|
+
return this.withMiddleware(...middlewares);
|
|
148
|
+
}
|
|
149
|
+
async request(context, initOverrides) {
|
|
150
|
+
const { url, init } = await this.createFetchParams(context, initOverrides);
|
|
151
|
+
const response = await this.fetchApi(url, init);
|
|
152
|
+
if (response && (response.status >= 200 && response.status < 300)) {
|
|
153
|
+
return response;
|
|
154
|
+
}
|
|
155
|
+
throw new ResponseError(response, "Response returned an error code");
|
|
156
|
+
}
|
|
157
|
+
async createFetchParams(context, initOverrides) {
|
|
158
|
+
let url = this.configuration.basePath + context.path;
|
|
159
|
+
if (context.query !== void 0 && Object.keys(context.query).length !== 0) {
|
|
160
|
+
url += "?" + this.configuration.queryParamsStringify(context.query);
|
|
161
|
+
}
|
|
162
|
+
const headers = Object.assign({}, this.configuration.headers, context.headers);
|
|
163
|
+
Object.keys(headers).forEach((key) => headers[key] === void 0 ? delete headers[key] : {});
|
|
164
|
+
const initOverrideFn = typeof initOverrides === "function" ? initOverrides : async () => initOverrides;
|
|
165
|
+
const initParams = {
|
|
166
|
+
method: context.method,
|
|
167
|
+
headers,
|
|
168
|
+
body: context.body,
|
|
169
|
+
credentials: this.configuration.credentials
|
|
170
|
+
};
|
|
171
|
+
const overriddenInit = {
|
|
172
|
+
...initParams,
|
|
173
|
+
...await initOverrideFn({
|
|
174
|
+
init: initParams,
|
|
175
|
+
context
|
|
176
|
+
})
|
|
177
|
+
};
|
|
178
|
+
const init = {
|
|
179
|
+
...overriddenInit,
|
|
180
|
+
body: isFormData(overriddenInit.body) || overriddenInit.body instanceof URLSearchParams || isBlob(overriddenInit.body) ? overriddenInit.body : JSON.stringify(overriddenInit.body)
|
|
181
|
+
};
|
|
182
|
+
return { url, init };
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Create a shallow clone of `this` by constructing a new instance
|
|
186
|
+
* and then shallow cloning data members.
|
|
187
|
+
*/
|
|
188
|
+
clone() {
|
|
189
|
+
const constructor = this.constructor;
|
|
190
|
+
const next = new constructor(this.configuration);
|
|
191
|
+
next.middleware = this.middleware.slice();
|
|
192
|
+
return next;
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
function isBlob(value) {
|
|
196
|
+
return typeof Blob !== "undefined" && value instanceof Blob;
|
|
197
|
+
}
|
|
198
|
+
function isFormData(value) {
|
|
199
|
+
return typeof FormData !== "undefined" && value instanceof FormData;
|
|
200
|
+
}
|
|
201
|
+
var ResponseError = class extends Error {
|
|
202
|
+
constructor(response, msg) {
|
|
203
|
+
super(msg);
|
|
204
|
+
this.response = response;
|
|
205
|
+
this.name = "ResponseError";
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
var FetchError = class extends Error {
|
|
209
|
+
constructor(cause, msg) {
|
|
210
|
+
super(msg);
|
|
211
|
+
this.cause = cause;
|
|
212
|
+
this.name = "FetchError";
|
|
213
|
+
}
|
|
214
|
+
};
|
|
86
215
|
function querystring(params, prefix = "") {
|
|
87
216
|
return Object.keys(params).map((key) => querystringSingleKey(key, params[key], prefix)).filter((part) => part.length > 0).join("&");
|
|
88
217
|
}
|
|
@@ -943,11 +1072,12 @@ async function generateAuthToken({ apiKeyId, issuerId, privateKey, expirationTim
|
|
|
943
1072
|
kid: apiKeyId,
|
|
944
1073
|
// The type of the token (JWT)
|
|
945
1074
|
typ: "JWT"
|
|
946
|
-
}).setIssuer(issuerId).setAudience("appstoreconnect-v1").setExpirationTime(expirationTime
|
|
1075
|
+
}).setIssuer(issuerId).setAudience("appstoreconnect-v1").setExpirationTime(expirationTime).sign(key);
|
|
947
1076
|
return token;
|
|
948
1077
|
}
|
|
949
1078
|
|
|
950
1079
|
// src/main.ts
|
|
1080
|
+
var DEFAULT_EXPIRATION_DURATION_SECONDS = 60 * 20;
|
|
951
1081
|
var AppStoreConnectAPI = class {
|
|
952
1082
|
/**
|
|
953
1083
|
* Creates an instance of the AppStoreConnectAPI.
|
|
@@ -957,13 +1087,15 @@ var AppStoreConnectAPI = class {
|
|
|
957
1087
|
* @param options.privateKey - The content of the private key used for generating JWT token.
|
|
958
1088
|
* @param options.fetchApi - (Optional) The FetchAPI implementation to use for API requests.
|
|
959
1089
|
* @param options.bearerToken - (Optional) A pre-generated bearer token to use for authentication.
|
|
960
|
-
* @param options.
|
|
1090
|
+
* @param options.expirationDuration - (Optional) The expiration duration for the bearer token in seconds (default 20 minutes).
|
|
961
1091
|
* @param options.basePath - (Optional) The base path for the API (without trailing slash, default https://api.appstoreconnect.apple.com).
|
|
962
1092
|
* @throws {string} Will throw an error if no bearerToken or private key is provided
|
|
963
1093
|
*/
|
|
964
1094
|
constructor(options) {
|
|
1095
|
+
/**
|
|
1096
|
+
* The time (in milliseconds) when the current bearer token was generated.
|
|
1097
|
+
*/
|
|
965
1098
|
this.bearerTokenGeneratedAt = 0;
|
|
966
|
-
if (options.expirationTime) options.expirationTime = options.expirationTime;
|
|
967
1099
|
this.options = options;
|
|
968
1100
|
}
|
|
969
1101
|
/**
|
|
@@ -972,16 +1104,16 @@ var AppStoreConnectAPI = class {
|
|
|
972
1104
|
async genToken() {
|
|
973
1105
|
if (this.options.bearerToken) {
|
|
974
1106
|
return this.options.bearerToken;
|
|
975
|
-
}
|
|
1107
|
+
}
|
|
1108
|
+
if (this.options.privateKeyId && this.options.issuerId && this.options.privateKey) {
|
|
976
1109
|
return await generateAuthToken({
|
|
977
1110
|
apiKeyId: this.options.privateKeyId,
|
|
978
1111
|
issuerId: this.options.issuerId,
|
|
979
1112
|
privateKey: this.options.privateKey,
|
|
980
|
-
expirationTime: this.options.
|
|
1113
|
+
expirationTime: Math.floor(Date.now() / 1e3) + (this.options.expirationDuration ?? DEFAULT_EXPIRATION_DURATION_SECONDS)
|
|
981
1114
|
});
|
|
982
|
-
} else {
|
|
983
|
-
throw "No bearerToken!!!";
|
|
984
1115
|
}
|
|
1116
|
+
throw "No bearerToken or private key provided";
|
|
985
1117
|
}
|
|
986
1118
|
/**
|
|
987
1119
|
* Create a Configuration object with the authentication token and any provided FetchAPI implementation.
|
|
@@ -1000,7 +1132,9 @@ var AppStoreConnectAPI = class {
|
|
|
1000
1132
|
* Returns the current bearer token, generating a new one if necessary.
|
|
1001
1133
|
*/
|
|
1002
1134
|
async getConfiguration() {
|
|
1003
|
-
const
|
|
1135
|
+
const latestBearerTokenDuration = this.bearerTokenGeneratedAt ? Date.now() - this.bearerTokenGeneratedAt : 0;
|
|
1136
|
+
const expirationDurationMs = 1e3 * (this.options.expirationDuration ?? DEFAULT_EXPIRATION_DURATION_SECONDS);
|
|
1137
|
+
const hasExpired = latestBearerTokenDuration > expirationDurationMs;
|
|
1004
1138
|
if (!this.configuration || hasExpired) {
|
|
1005
1139
|
await this.genConfiguration();
|
|
1006
1140
|
}
|
|
@@ -1014,6 +1148,39 @@ var AppStoreConnectAPI = class {
|
|
|
1014
1148
|
async create(apiClass) {
|
|
1015
1149
|
return new apiClass(await this.getConfiguration());
|
|
1016
1150
|
}
|
|
1151
|
+
/**
|
|
1152
|
+
* Makes an API request.
|
|
1153
|
+
* @param context - The request context for the API request.
|
|
1154
|
+
* @param initOverrides - (Optional) The request options to use for the API request.
|
|
1155
|
+
* @returns The response from the API request.
|
|
1156
|
+
*/
|
|
1157
|
+
async request(context, initOverrides) {
|
|
1158
|
+
if (!context.url && !context.path) {
|
|
1159
|
+
throw new Error("No url or path provided");
|
|
1160
|
+
}
|
|
1161
|
+
const _context = { ...context };
|
|
1162
|
+
if (!_context.path && _context.url) {
|
|
1163
|
+
if (_context.url.startsWith(BASE_PATH)) {
|
|
1164
|
+
_context.path = _context.url.replace(BASE_PATH, "");
|
|
1165
|
+
} else {
|
|
1166
|
+
throw new Error("url must start with " + BASE_PATH);
|
|
1167
|
+
}
|
|
1168
|
+
}
|
|
1169
|
+
if (!_context.method) {
|
|
1170
|
+
_context.method = "GET";
|
|
1171
|
+
}
|
|
1172
|
+
delete _context.url;
|
|
1173
|
+
const globalApi = new GlobalAPI(await this.getConfiguration());
|
|
1174
|
+
return await globalApi.request(_context, initOverrides);
|
|
1175
|
+
}
|
|
1176
|
+
};
|
|
1177
|
+
var GlobalAPI = class extends BaseAPI {
|
|
1178
|
+
constructor(configuration) {
|
|
1179
|
+
super(configuration);
|
|
1180
|
+
}
|
|
1181
|
+
request(context, initOverrides) {
|
|
1182
|
+
return super.request(context, initOverrides);
|
|
1183
|
+
}
|
|
1017
1184
|
};
|
|
1018
1185
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1019
1186
|
0 && (module.exports = {
|