@tryghost/content-api 1.6.2 → 1.7.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.
@@ -2,11 +2,38 @@
2
2
 
3
3
  var axios = require('axios');
4
4
 
5
- const supportedVersions = ['v2', 'v3', 'v4', 'canary'];
5
+ const supportedVersions = ['v2', 'v3', 'v4', 'v5', 'canary'];
6
6
  const name = '@tryghost/content-api';
7
7
 
8
- function GhostContentAPI({url, host, ghostPath = 'ghost', version, key}) {
9
- // host parameter is deprecated
8
+ const defaultMakeRequest = ({url, method, params, headers}) => {
9
+ return axios[method](url, {
10
+ params,
11
+ paramsSerializer: (parameters) => {
12
+ return Object.keys(parameters).reduce((parts, k) => {
13
+ const val = encodeURIComponent([].concat(parameters[k]).join(','));
14
+ return parts.concat(`${k}=${val}`);
15
+ }, []).join('&');
16
+ },
17
+ headers
18
+ });
19
+ };
20
+
21
+ /**
22
+ *
23
+ * @param {Object} options
24
+ * @param {String} options.url
25
+ * @param {String} options.key
26
+ * @param {String} [options.ghostPath]
27
+ * @param {String} [options.version]
28
+ * @param {Function} [options.makeRequest]
29
+ * @param {String} [options.host] Deprecated
30
+ * @returns
31
+ */
32
+ function GhostContentAPI({url, key, host, version, ghostPath = 'ghost', makeRequest = defaultMakeRequest}) {
33
+ /**
34
+ * host parameter is deprecated
35
+ * @deprecated use "url" instead
36
+ */
10
37
  if (host) {
11
38
  // eslint-disable-next-line
12
39
  console.warn(`${name}: The 'host' parameter is deprecated, please use 'url' instead`);
@@ -16,13 +43,10 @@ function GhostContentAPI({url, host, ghostPath = 'ghost', version, key}) {
16
43
  }
17
44
 
18
45
  if (this instanceof GhostContentAPI) {
19
- return GhostContentAPI({url, version, key});
46
+ return GhostContentAPI({url, key, version, ghostPath, makeRequest});
20
47
  }
21
48
 
22
- if (!version) {
23
- throw new Error(`${name} Config Missing: 'version' is required. E.g. ${supportedVersions.join(',')}`);
24
- }
25
- if (!supportedVersions.includes(version)) {
49
+ if (version && !supportedVersions.includes(version)) {
26
50
  throw new Error(`${name} Config Invalid: 'version' ${version} is not supported`);
27
51
  }
28
52
  if (!url) {
@@ -42,7 +66,7 @@ function GhostContentAPI({url, host, ghostPath = 'ghost', version, key}) {
42
66
  }
43
67
  const api = ['posts', 'authors', 'tags', 'pages', 'settings'].reduce((apiObject, resourceType) => {
44
68
  function browse(options = {}, memberToken) {
45
- return makeRequest(resourceType, options, null, memberToken);
69
+ return makeApiRequest(resourceType, options, null, memberToken);
46
70
  }
47
71
  function read(data, options = {}, memberToken) {
48
72
  if (!data || !data.id && !data.slug) {
@@ -51,7 +75,7 @@ function GhostContentAPI({url, host, ghostPath = 'ghost', version, key}) {
51
75
 
52
76
  const params = Object.assign({}, data, options);
53
77
 
54
- return makeRequest(resourceType, params, data.id || `slug/${data.slug}`, memberToken);
78
+ return makeApiRequest(resourceType, params, data.id || `slug/${data.slug}`, memberToken);
55
79
  }
56
80
 
57
81
  return Object.assign(apiObject, {
@@ -66,7 +90,7 @@ function GhostContentAPI({url, host, ghostPath = 'ghost', version, key}) {
66
90
 
67
91
  return api;
68
92
 
69
- function makeRequest(resourceType, params, id, membersToken = null) {
93
+ function makeApiRequest(resourceType, params, id, membersToken = null) {
70
94
  if (!membersToken && !key) {
71
95
  return Promise.reject(
72
96
  new Error(`${name} Config Missing: 'key' is required.`)
@@ -76,48 +100,54 @@ function GhostContentAPI({url, host, ghostPath = 'ghost', version, key}) {
76
100
 
77
101
  const headers = membersToken ? {
78
102
  Authorization: `GhostMembers ${membersToken}`
79
- } : undefined;
80
-
81
- return axios.get(`${url}/${ghostPath}/api/${version}/content/${resourceType}/${id ? id + '/' : ''}`, {
82
- params: Object.assign({key}, params),
83
- paramsSerializer: (parameters) => {
84
- return Object.keys(parameters).reduce((parts, k) => {
85
- const val = encodeURIComponent([].concat(parameters[k]).join(','));
86
- return parts.concat(`${k}=${val}`);
87
- }, []).join('&');
88
- },
89
- headers
90
- }).then((res) => {
91
- if (!Array.isArray(res.data[resourceType])) {
92
- return res.data[resourceType];
93
- }
94
- if (res.data[resourceType].length === 1 && !res.data.meta) {
95
- return res.data[resourceType][0];
96
- }
97
- return Object.assign(res.data[resourceType], {meta: res.data.meta});
98
- }).catch((err) => {
99
- if (err.response && err.response.data && err.response.data.errors) {
100
- const props = err.response.data.errors[0];
101
- const toThrow = new Error(props.message);
102
- const keys = Object.keys(props);
103
-
104
- toThrow.name = props.type;
103
+ } : {};
105
104
 
106
- keys.forEach((k) => {
107
- toThrow[k] = props[k];
108
- });
109
-
110
- toThrow.response = err.response;
105
+ if (!version || ['v4', 'v5', 'canary'].includes(version)) {
106
+ headers['Accept-Version'] = version || 'v5';
107
+ }
111
108
 
112
- // @TODO: remove in 2.0. We have enhanced the error handling, but we don't want to break existing implementations.
113
- toThrow.request = err.request;
114
- toThrow.config = err.config;
109
+ params = Object.assign({key}, params);
110
+ const apiUrl = version
111
+ ? `${url}/${ghostPath}/api/${version}/content/${resourceType}/${id ? id + '/' : ''}`
112
+ : `${url}/${ghostPath}/api/content/${resourceType}/${id ? id + '/' : ''}`;
115
113
 
116
- throw toThrow;
117
- } else {
118
- throw err;
119
- }
120
- });
114
+ return makeRequest({
115
+ url: apiUrl,
116
+ method: 'get',
117
+ params,
118
+ headers
119
+ })
120
+ .then((res) => {
121
+ if (!Array.isArray(res.data[resourceType])) {
122
+ return res.data[resourceType];
123
+ }
124
+ if (res.data[resourceType].length === 1 && !res.data.meta) {
125
+ return res.data[resourceType][0];
126
+ }
127
+ return Object.assign(res.data[resourceType], {meta: res.data.meta});
128
+ }).catch((err) => {
129
+ if (err.response && err.response.data && err.response.data.errors) {
130
+ const props = err.response.data.errors[0];
131
+ const toThrow = new Error(props.message);
132
+ const keys = Object.keys(props);
133
+
134
+ toThrow.name = props.type;
135
+
136
+ keys.forEach((k) => {
137
+ toThrow[k] = props[k];
138
+ });
139
+
140
+ toThrow.response = err.response;
141
+
142
+ // @TODO: remove in 2.0. We have enhanced the error handling, but we don't want to break existing implementations.
143
+ toThrow.request = err.request;
144
+ toThrow.config = err.config;
145
+
146
+ throw toThrow;
147
+ } else {
148
+ throw err;
149
+ }
150
+ });
121
151
  }
122
152
  }
123
153