@tryghost/admin-api 1.6.0 → 1.8.1
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/lib/index.js +81 -33
- package/lib/token.js +9 -2
- package/package.json +2 -2
package/lib/index.js
CHANGED
|
@@ -3,9 +3,18 @@ const FormData = require('form-data');
|
|
|
3
3
|
const fs = require('fs');
|
|
4
4
|
const token = require('./token');
|
|
5
5
|
|
|
6
|
-
const supportedVersions = ['v2', 'v3', 'v4', 'canary'];
|
|
6
|
+
const supportedVersions = ['v2', 'v3', 'v4', 'v5', 'canary'];
|
|
7
7
|
const packageName = '@tryghost/admin-api';
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
*
|
|
11
|
+
* @param {Object} options
|
|
12
|
+
* @param {String} options.url
|
|
13
|
+
* @param {String} [options.ghostPath]
|
|
14
|
+
* @param {String} [options.version]
|
|
15
|
+
* @param {Function} [options.makeRequest]
|
|
16
|
+
* @param {String} [options.host] Deprecated
|
|
17
|
+
*/
|
|
9
18
|
module.exports = function GhostAdminAPI(options) {
|
|
10
19
|
if (this instanceof GhostAdminAPI) {
|
|
11
20
|
return GhostAdminAPI(options);
|
|
@@ -35,7 +44,12 @@ module.exports = function GhostAdminAPI(options) {
|
|
|
35
44
|
|
|
36
45
|
const config = Object.assign({}, defaultConfig, options);
|
|
37
46
|
|
|
38
|
-
//
|
|
47
|
+
//
|
|
48
|
+
/**
|
|
49
|
+
* host parameter is deprecated
|
|
50
|
+
* @deprecated use "url" instead
|
|
51
|
+
* @example new GhostAdminAPI({host: '...'})
|
|
52
|
+
*/
|
|
39
53
|
if (config.host) {
|
|
40
54
|
// eslint-disable-next-line
|
|
41
55
|
console.warn(`${packageName}: The 'host' parameter is deprecated, please use 'url' instead`);
|
|
@@ -44,10 +58,7 @@ module.exports = function GhostAdminAPI(options) {
|
|
|
44
58
|
}
|
|
45
59
|
}
|
|
46
60
|
|
|
47
|
-
if (!config.version) {
|
|
48
|
-
throw new Error(`${packageName} Config Missing: 'version' is required. E.g. ${supportedVersions.join(',')}`);
|
|
49
|
-
}
|
|
50
|
-
if (!supportedVersions.includes(config.version)) {
|
|
61
|
+
if (config.version && !supportedVersions.includes(config.version)) {
|
|
51
62
|
throw new Error(`${packageName} Config Invalid: 'version' ${config.version} is not supported`);
|
|
52
63
|
}
|
|
53
64
|
if (!config.url) {
|
|
@@ -69,6 +80,11 @@ module.exports = function GhostAdminAPI(options) {
|
|
|
69
80
|
throw new Error(`${packageName} Config Invalid: 'key' ${config.key} must have the following format {A}:{B}, where A is 24 hex characters and B is 64 hex characters`);
|
|
70
81
|
}
|
|
71
82
|
|
|
83
|
+
if (config.version === 'v5') {
|
|
84
|
+
// NOTE: the version parameter is supported but not necessary for non-versioned API, starting with Ghost v5
|
|
85
|
+
delete config.version;
|
|
86
|
+
}
|
|
87
|
+
|
|
72
88
|
const resources = [
|
|
73
89
|
// @NOTE: stable
|
|
74
90
|
'posts',
|
|
@@ -202,29 +218,52 @@ module.exports = function GhostAdminAPI(options) {
|
|
|
202
218
|
if (data.file) {
|
|
203
219
|
formData = new FormData();
|
|
204
220
|
formData.append('file', fs.createReadStream(data.file));
|
|
221
|
+
// NOTE: this default "image" doesn't work for all upload endpoints. Should be moved from here and required as
|
|
222
|
+
// an explicit method parameter. Leaving it here for now as I'm focusing on a different problem.
|
|
205
223
|
formData.append('purpose', data.purpose || 'image');
|
|
206
224
|
|
|
207
225
|
if (data.ref) {
|
|
208
226
|
formData.append('ref', data.ref);
|
|
209
227
|
}
|
|
210
228
|
|
|
229
|
+
if (data.thumbnail) {
|
|
230
|
+
formData.append('thumbnail', fs.createReadStream(data.thumbnail));
|
|
231
|
+
}
|
|
232
|
+
|
|
211
233
|
return formData;
|
|
212
234
|
}
|
|
213
235
|
}
|
|
214
236
|
|
|
215
237
|
api.images = {
|
|
216
238
|
upload(data) {
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
if (!isValidUpload(data)) {
|
|
222
|
-
return Promise.reject(new Error('Must be of FormData or include path'));
|
|
223
|
-
}
|
|
239
|
+
return makeUploadRequest('images', data, endpointFor('images/upload'));
|
|
240
|
+
}
|
|
241
|
+
};
|
|
224
242
|
|
|
225
|
-
|
|
243
|
+
api.media = {
|
|
244
|
+
/**
|
|
245
|
+
*
|
|
246
|
+
* @param {Object} data
|
|
247
|
+
* @param {String} data.file - file path to a media file
|
|
248
|
+
* @param {String} [data.thumbnail] - file path to a thumbnail file
|
|
249
|
+
* @param {String} [data.purpose]
|
|
250
|
+
* @returns Promise<Object>
|
|
251
|
+
*/
|
|
252
|
+
upload(data) {
|
|
253
|
+
return makeUploadRequest('media', data, endpointFor('media/upload'));
|
|
254
|
+
}
|
|
255
|
+
};
|
|
226
256
|
|
|
227
|
-
|
|
257
|
+
api.files = {
|
|
258
|
+
/**
|
|
259
|
+
*
|
|
260
|
+
* @param {Object} data
|
|
261
|
+
* @param {String} data.file - file path to a media file
|
|
262
|
+
* @param {String} [data.ref] - reference field returned in the response
|
|
263
|
+
* @returns Promise<Object>
|
|
264
|
+
*/
|
|
265
|
+
upload(data) {
|
|
266
|
+
return makeUploadRequest('files', data, endpointFor('files/upload'));
|
|
228
267
|
}
|
|
229
268
|
};
|
|
230
269
|
|
|
@@ -242,17 +281,7 @@ module.exports = function GhostAdminAPI(options) {
|
|
|
242
281
|
|
|
243
282
|
api.themes = {
|
|
244
283
|
upload(data) {
|
|
245
|
-
|
|
246
|
-
return Promise.reject(new Error('Missing data'));
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
if (!isValidUpload(data)) {
|
|
250
|
-
return Promise.reject(new Error('Must be of FormData or include path'));
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
let formData = getFormData(data);
|
|
254
|
-
|
|
255
|
-
return makeUploadRequest('themes', formData, endpointFor('themes/upload'));
|
|
284
|
+
return makeUploadRequest('themes', data, endpointFor('themes/upload'));
|
|
256
285
|
},
|
|
257
286
|
activate(name) {
|
|
258
287
|
if (!name) {
|
|
@@ -266,14 +295,24 @@ module.exports = function GhostAdminAPI(options) {
|
|
|
266
295
|
return api;
|
|
267
296
|
|
|
268
297
|
function makeUploadRequest(resourceType, data, endpoint) {
|
|
298
|
+
if (!data) {
|
|
299
|
+
return Promise.reject(new Error('Missing data'));
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
if (!isValidUpload(data)) {
|
|
303
|
+
return Promise.reject(new Error('Must be of FormData or include path'));
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
let formData = getFormData(data);
|
|
307
|
+
|
|
269
308
|
const headers = {
|
|
270
|
-
'Content-Type': `multipart/form-data; boundary=${
|
|
309
|
+
'Content-Type': `multipart/form-data; boundary=${formData._boundary}`
|
|
271
310
|
};
|
|
272
311
|
|
|
273
312
|
return makeApiRequest({
|
|
274
313
|
endpoint: endpoint,
|
|
275
314
|
method: 'POST',
|
|
276
|
-
body:
|
|
315
|
+
body: formData,
|
|
277
316
|
headers
|
|
278
317
|
}).then((apiData) => {
|
|
279
318
|
if (!Array.isArray(apiData[resourceType])) {
|
|
@@ -308,7 +347,10 @@ module.exports = function GhostAdminAPI(options) {
|
|
|
308
347
|
|
|
309
348
|
function endpointFor(resource, {id, slug, email} = {}) {
|
|
310
349
|
const {ghostPath, version} = config;
|
|
311
|
-
|
|
350
|
+
|
|
351
|
+
let endpoint = version
|
|
352
|
+
? `/${ghostPath}/api/${version}/admin/${resource}/`
|
|
353
|
+
: `/${ghostPath}/api/admin/${resource}/`;
|
|
312
354
|
|
|
313
355
|
if (id) {
|
|
314
356
|
endpoint = `${endpoint}${id}/`;
|
|
@@ -325,9 +367,15 @@ module.exports = function GhostAdminAPI(options) {
|
|
|
325
367
|
const {url: apiUrl, key, version, makeRequest} = config;
|
|
326
368
|
const url = `${apiUrl}${endpoint}`;
|
|
327
369
|
|
|
328
|
-
|
|
329
|
-
Authorization: `Ghost ${token(
|
|
330
|
-
}
|
|
370
|
+
const ghostHeaders = {
|
|
371
|
+
Authorization: `Ghost ${token(key, version)}`
|
|
372
|
+
};
|
|
373
|
+
|
|
374
|
+
if (!version || ['v4', 'canary'].includes(version)) {
|
|
375
|
+
ghostHeaders['Accept-Version'] = version || 'v5';
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
headers = Object.assign({}, headers, ghostHeaders);
|
|
331
379
|
|
|
332
380
|
return makeRequest({
|
|
333
381
|
url,
|
|
@@ -339,7 +387,7 @@ module.exports = function GhostAdminAPI(options) {
|
|
|
339
387
|
/**
|
|
340
388
|
* @NOTE:
|
|
341
389
|
*
|
|
342
|
-
* If you are overriding `makeRequest`, we can't
|
|
390
|
+
* If you are overriding `makeRequest`, we can't garante that the returned format is the same, but
|
|
343
391
|
* we try to detect & return a proper error instance.
|
|
344
392
|
*/
|
|
345
393
|
if (err.response && err.response.data && err.response.data.errors) {
|
package/lib/token.js
CHANGED
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
const jwt = require('jsonwebtoken');
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param {String} key - API key to sign JWT with
|
|
6
|
+
* @param {String} version - API version to use as a part of audience
|
|
7
|
+
* @returns
|
|
8
|
+
*/
|
|
9
|
+
module.exports = function token(key, version) {
|
|
4
10
|
const [id, secret] = key.split(':');
|
|
11
|
+
const audience = version ? `/${version}/admin/` : '/admin/';
|
|
5
12
|
|
|
6
13
|
return jwt.sign({}, Buffer.from(secret, 'hex'), { // eslint-disable-line no-undef
|
|
7
14
|
keyid: id,
|
|
8
15
|
algorithm: 'HS256',
|
|
9
16
|
expiresIn: '5m',
|
|
10
|
-
audience
|
|
17
|
+
audience
|
|
11
18
|
});
|
|
12
19
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tryghost/admin-api",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.1",
|
|
4
4
|
"repository": "https://github.com/TryGhost/SDK/tree/master/packages/admin-api",
|
|
5
5
|
"author": "Ghost Foundation",
|
|
6
6
|
"license": "MIT",
|
|
@@ -31,5 +31,5 @@
|
|
|
31
31
|
"form-data": "^4.0.0",
|
|
32
32
|
"jsonwebtoken": "^8.4.0"
|
|
33
33
|
},
|
|
34
|
-
"gitHead": "
|
|
34
|
+
"gitHead": "dbf4ab41a6964422987a68c4327336692a54527f"
|
|
35
35
|
}
|