@tryghost/admin-api 1.8.1 → 1.10.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/lib/index.js CHANGED
@@ -3,16 +3,39 @@ const FormData = require('form-data');
3
3
  const fs = require('fs');
4
4
  const token = require('./token');
5
5
 
6
+ // NOTE: bump this default when Ghost v5 is released
7
+ const defaultAcceptVersionHeader = 'v4.0';
6
8
  const supportedVersions = ['v2', 'v3', 'v4', 'v5', 'canary'];
7
9
  const packageName = '@tryghost/admin-api';
8
10
 
11
+ /**
12
+ * This method can go away in favor of only sending 'Accept-Version` headers
13
+ * once the Ghost API removes a concept of version from it's URLS (with Ghost v5)
14
+ *
15
+ * @param {string} [version] version in `v{major}` format
16
+ * @returns {string}
17
+ */
18
+ const resolveAPIPrefix = (version) => {
19
+ let prefix;
20
+
21
+ // NOTE: the "version.match(/^v5\.\d+/)" expression should be changed to "version.match(/^v\d+\.\d+/)" once Ghost v5 is out
22
+ if (version === 'v5' || version === undefined || version.match(/^v5\.\d+/)) {
23
+ prefix = `/admin/`;
24
+ } else {
25
+ prefix = `/${version}/admin/`;
26
+ }
27
+
28
+ return prefix;
29
+ };
30
+
9
31
  /**
10
32
  *
11
33
  * @param {Object} options
12
34
  * @param {String} options.url
13
35
  * @param {String} [options.ghostPath]
14
- * @param {String} [options.version]
36
+ * @param {String|Boolean} options.version - a version string like v3.2, v4.1, v5.8 or boolean value identifying presence of Accept-Version header
15
37
  * @param {Function} [options.makeRequest]
38
+ * @param {Function} [options.generateToken]
16
39
  * @param {String} [options.host] Deprecated
17
40
  */
18
41
  module.exports = function GhostAdminAPI(options) {
@@ -22,6 +45,7 @@ module.exports = function GhostAdminAPI(options) {
22
45
 
23
46
  const defaultConfig = {
24
47
  ghostPath: 'ghost',
48
+ generateToken: token,
25
49
  makeRequest({url, method, data, params = {}, headers = {}}) {
26
50
  return axios({
27
51
  url,
@@ -58,9 +82,34 @@ module.exports = function GhostAdminAPI(options) {
58
82
  }
59
83
  }
60
84
 
61
- if (config.version && !supportedVersions.includes(config.version)) {
85
+ if (config.version === undefined) {
86
+ throw new Error(`${packageName} Config Missing: 'version' is required. E.g. ${supportedVersions.join(',')}`);
87
+ }
88
+
89
+ if (typeof config.version === 'boolean') {
90
+ if (config.version === true) {
91
+ config.acceptVersionHeader = defaultAcceptVersionHeader;
92
+ }
93
+ config.version = undefined;
94
+ } else if (!supportedVersions.includes(config.version) && !(config.version.match(/^v\d+\.\d+/))) {
62
95
  throw new Error(`${packageName} Config Invalid: 'version' ${config.version} is not supported`);
96
+ } else if (supportedVersions.includes(config.version) || config.version.match(/^v\d+\.\d+/)) {
97
+ if (config.version === 'canary') {
98
+ // eslint-disable-next-line
99
+ console.warn(`${packageName}: The 'version' parameter has a deprecated format 'canary', please use 'v{major}.{minor}' format instead`);
100
+
101
+ config.acceptVersionHeader = defaultAcceptVersionHeader;
102
+ } else if (config.version.match(/^v\d+$/)) {
103
+ // eslint-disable-next-line
104
+ console.warn(`${packageName}: The 'version' parameter has a deprecated format 'v{major}', please use 'v{major}.{minor}' format instead`);
105
+
106
+ // CASE: all the v1, v2, v4 ... strings should be normalized to fit 'v{major}.{minor}' format
107
+ config.acceptVersionHeader = `${config.version}.0`;
108
+ } else {
109
+ config.acceptVersionHeader = config.version;
110
+ }
63
111
  }
112
+
64
113
  if (!config.url) {
65
114
  throw new Error(`${packageName} Config Missing: 'url' is required. E.g. 'https://site.com'`);
66
115
  }
@@ -80,22 +129,19 @@ module.exports = function GhostAdminAPI(options) {
80
129
  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`);
81
130
  }
82
131
 
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
-
88
132
  const resources = [
89
- // @NOTE: stable
90
133
  'posts',
91
134
  'pages',
92
135
  'tags',
93
136
  'webhooks',
94
137
  'members',
95
- // @NOTE: experimental
96
138
  'users'
97
139
  ];
98
140
 
141
+ if (typeof config.version === 'string' && config.version.startsWith('v2')) {
142
+ resources.push('subscribers');
143
+ }
144
+
99
145
  const api = resources.reduce((apiObject, resourceType) => {
100
146
  function add(data, queryParams = {}) {
101
147
  if (!data || !Object.keys(data).length) {
@@ -348,9 +394,8 @@ module.exports = function GhostAdminAPI(options) {
348
394
  function endpointFor(resource, {id, slug, email} = {}) {
349
395
  const {ghostPath, version} = config;
350
396
 
351
- let endpoint = version
352
- ? `/${ghostPath}/api/${version}/admin/${resource}/`
353
- : `/${ghostPath}/api/admin/${resource}/`;
397
+ const apiPrefix = resolveAPIPrefix(version);
398
+ let endpoint = `/${ghostPath}/api${apiPrefix}${resource}/`;
354
399
 
355
400
  if (id) {
356
401
  endpoint = `${endpoint}${id}/`;
@@ -367,12 +412,16 @@ module.exports = function GhostAdminAPI(options) {
367
412
  const {url: apiUrl, key, version, makeRequest} = config;
368
413
  const url = `${apiUrl}${endpoint}`;
369
414
 
415
+ let authorizationHeader;
416
+ const audience = resolveAPIPrefix(version);
417
+ authorizationHeader = `Ghost ${config.generateToken(key, audience)}`;
418
+
370
419
  const ghostHeaders = {
371
- Authorization: `Ghost ${token(key, version)}`
420
+ Authorization: authorizationHeader
372
421
  };
373
422
 
374
- if (!version || ['v4', 'canary'].includes(version)) {
375
- ghostHeaders['Accept-Version'] = version || 'v5';
423
+ if (config.acceptVersionHeader) {
424
+ ghostHeaders['Accept-Version'] = config.acceptVersionHeader;
376
425
  }
377
426
 
378
427
  headers = Object.assign({}, headers, ghostHeaders);
package/lib/token.js CHANGED
@@ -3,12 +3,11 @@ const jwt = require('jsonwebtoken');
3
3
  /**
4
4
  *
5
5
  * @param {String} key - API key to sign JWT with
6
- * @param {String} version - API version to use as a part of audience
6
+ * @param {String} audience - token audience
7
7
  * @returns
8
8
  */
9
- module.exports = function token(key, version) {
9
+ module.exports = function token(key, audience) {
10
10
  const [id, secret] = key.split(':');
11
- const audience = version ? `/${version}/admin/` : '/admin/';
12
11
 
13
12
  return jwt.sign({}, Buffer.from(secret, 'hex'), { // eslint-disable-line no-undef
14
13
  keyid: id,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tryghost/admin-api",
3
- "version": "1.8.1",
3
+ "version": "1.10.0",
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": "dbf4ab41a6964422987a68c4327336692a54527f"
34
+ "gitHead": "af2e0206c91195715d42b1640f453204abef5a5d"
35
35
  }