@tryghost/url-utils 2.1.0 → 4.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.
package/index.js ADDED
@@ -0,0 +1 @@
1
+ module.exports = require('./lib/url-utils');
@@ -18,65 +18,30 @@ module.exports = class UrlUtils {
18
18
  * @param {Function} options.getSubdir
19
19
  * @param {Function} options.getSiteUrl
20
20
  * @param {Function} options.getAdminUrl Ghost instance admin URL
21
- * @param {Object} options.apiVersions configuration object which has defined `all` property which is an array of keys for other available properties
22
- * @param {('v2' | 'v3' | 'v4' | 'canary')} [options.defaultApiVersion='v4'] default API version which is one of the values from options.apiVersions
23
- * @param {('content' | 'admin')} [options.defaultApiType='content'] default API type to be used and is one of the values from options.apiVersions
21
+ * @param {String} [options.baseApiPath='/ghost/api'] static prefix for serving API. Should not te passed in, unless the API is being run under custom URL
22
+ * @param {('content' | 'admin')} [options.defaultApiType='content'] default API type to be used
24
23
  * @param {Object} [options.slugs] object with 2 properties reserved and protected containing arrays of special case slugs
25
24
  * @param {Number} [options.redirectCacheMaxAge]
26
- * @param {String} [options.baseApiPath='/ghost/api'] static prefix for serving API. Should not te passed in, unless the API is being run under custom URL
27
25
  * @param {String} [options.staticImageUrlPrefix='content/images'] static prefix for serving images. Should not be passed in, unless customizing ghost instance image storage
28
26
  */
29
27
  constructor(options = {}) {
30
28
  const defaultOptions = {
31
- apiVersions: null,
32
29
  slugs: null,
33
30
  redirectCacheMaxAge: null,
34
31
  baseApiPath: '/ghost/api',
35
- defaultApiVersion: 'v4',
36
32
  defaultApiType: 'content',
37
33
  staticImageUrlPrefix: 'content/images'
38
34
  };
39
35
 
40
36
  this._config = assignOptions({}, defaultOptions, options);
41
37
 
42
- this._defaultApiPathOptions = {
43
- baseApiPath: this._config.baseApiPath,
44
- version: this._config.defaultApiVersion,
45
- type: this._config.defaultApiType,
46
- apiVersions: this._config.apiVersions
47
- };
48
-
49
38
  this.getSubdir = options.getSubdir;
50
39
  this.getSiteUrl = options.getSiteUrl;
51
40
  this.getAdminUrl = options.getAdminUrl;
52
41
  }
53
42
 
54
- /**
55
- * Returns API path combining base path and path for specific version asked or deprecated by default
56
- * @param {Object} options
57
- * @param {string} [options.version="v4"] for which to get the path (v2, v3, canary, etc)
58
- * @param {string} [options.type="content"] (admin, content, members)
59
- * @return {string} API Path for version
60
- */
61
- getApiPath(options = {}) {
62
- const _options = assignOptions({}, this._defaultApiPathOptions, options);
63
- return utils.getApiPath(_options);
64
- }
65
-
66
- /**
67
- * Returns path containing only the path for the specific version asked or deprecated by default
68
- * @param {Object} options
69
- * @param {string} [options.version="v4"] for which to get the path (v2, v3, canary, etc)
70
- * @param {string} [options.type="content"] (admin, content)
71
- * @return {string} API version path
72
- */
73
- getVersionPath(options = {}) {
74
- const _options = assignOptions({}, this._defaultApiPathOptions, options);
75
- return utils.getVersionPath(_options);
76
- }
77
-
78
43
  getProtectedSlugs() {
79
- var subDir = this.getSubdir();
44
+ let subDir = this.getSubdir();
80
45
 
81
46
  if (!_.isEmpty(subDir)) {
82
47
  return this._config.slugs.concat([subDir.split('/').pop()]);
@@ -105,15 +70,14 @@ module.exports = class UrlUtils {
105
70
  // Parameters:
106
71
  // - urlPath - string which must start and end with a slash
107
72
  // - absolute (optional, default:false) - boolean whether or not the url should be absolute
108
- // - secure (optional, default:false) - boolean whether or not to force SSL
109
73
  // Returns:
110
74
  // - a URL which always ends with a slash
111
- createUrl(urlPath = '/', absolute = false, secure, trailingSlash) {
75
+ createUrl(urlPath = '/', absolute = false, trailingSlash) {
112
76
  let base;
113
77
 
114
78
  // create base of url, always ends without a slash
115
79
  if (absolute) {
116
- base = this.getSiteUrl(secure);
80
+ base = this.getSiteUrl();
117
81
  } else {
118
82
  base = this.getSubdir();
119
83
  }
@@ -143,18 +107,17 @@ module.exports = class UrlUtils {
143
107
  // This is probably not the right place for this, but it's the best place for now
144
108
  // @TODO: rewrite, very hard to read, create private functions!
145
109
  urlFor(context, data, absolute) {
146
- var urlPath = '/',
147
- secure,
148
- imagePathRe,
149
- knownObjects = ['image', 'nav'],
150
- baseUrl,
151
- hostname,
152
-
153
- // this will become really big
154
- knownPaths = {
155
- home: '/',
156
- sitemap_xsl: '/sitemap.xsl'
157
- };
110
+ let urlPath = '/';
111
+ let imagePathRe;
112
+ let knownObjects = ['image', 'nav'];
113
+ let baseUrl;
114
+ let hostname;
115
+
116
+ // this will become really big
117
+ let knownPaths = {
118
+ home: '/',
119
+ sitemap_xsl: '/sitemap.xsl'
120
+ };
158
121
 
159
122
  // Make data properly optional
160
123
  if (_.isBoolean(data)) {
@@ -162,9 +125,6 @@ module.exports = class UrlUtils {
162
125
  data = null;
163
126
  }
164
127
 
165
- // Can pass 'secure' flag in either context or data arg
166
- secure = (context && context.secure) || (data && data.secure);
167
-
168
128
  if (_.isObject(context) && context.relativeUrl) {
169
129
  urlPath = context.relativeUrl;
170
130
  } else if (_.isString(context) && _.indexOf(knownObjects, context) !== -1) {
@@ -176,15 +136,14 @@ module.exports = class UrlUtils {
176
136
  if (absolute) {
177
137
  // Remove the sub-directory from the URL because ghostConfig will add it back.
178
138
  urlPath = urlPath.replace(new RegExp('^' + this.getSubdir()), '');
179
- baseUrl = this.getSiteUrl(secure).replace(/\/$/, '');
139
+ baseUrl = this.getSiteUrl().replace(/\/$/, '');
180
140
  urlPath = baseUrl + urlPath;
181
141
  }
182
142
 
183
143
  return urlPath;
184
144
  } else if (context === 'nav' && data.nav) {
185
145
  urlPath = data.nav.url;
186
- secure = data.nav.secure || secure;
187
- baseUrl = this.getSiteUrl(secure);
146
+ baseUrl = this.getSiteUrl();
188
147
  hostname = baseUrl.split('//')[1];
189
148
 
190
149
  // If the hostname is present in the url
@@ -200,7 +159,7 @@ module.exports = class UrlUtils {
200
159
  }
201
160
  }
202
161
  } else if (context === 'home' && absolute) {
203
- urlPath = this.getSiteUrl(secure);
162
+ urlPath = this.getSiteUrl();
204
163
 
205
164
  // CASE: there are cases where urlFor('home') needs to be returned without trailing
206
165
  // slash e. g. the `{{@site.url}}` helper. See https://github.com/TryGhost/Ghost/issues/8569
@@ -208,32 +167,29 @@ module.exports = class UrlUtils {
208
167
  urlPath = urlPath.replace(/\/$/, '');
209
168
  }
210
169
  } else if (context === 'admin') {
211
- urlPath = this.getAdminUrl() || this.getSiteUrl();
170
+ let adminUrl = this.getAdminUrl() || this.getSiteUrl();
171
+ let adminPath = '/ghost/';
212
172
 
213
173
  if (absolute) {
214
- urlPath += 'ghost/';
174
+ urlPath = this.urlJoin(adminUrl, adminPath);
215
175
  } else {
216
- urlPath = '/ghost/';
176
+ urlPath = adminPath;
217
177
  }
218
178
  } else if (context === 'api') {
219
- urlPath = this.getAdminUrl() || this.getSiteUrl();
220
- let apiPath = this.getApiPath();
221
-
222
- // CASE: with or without protocol? If your blog url (or admin url) is configured to http, it's still possible that e.g. nginx allows both https+http.
223
- // So it depends how you serve your blog. The main focus here is to avoid cors problems.
224
- // @TODO: rename cors
225
- if (data && data.cors) {
226
- if (!urlPath.match(/^https:/)) {
227
- urlPath = urlPath.replace(/^.*?:\/\//g, '//');
228
- }
229
- }
179
+ let adminUrl = this.getAdminUrl() || this.getSiteUrl();
180
+ let apiPath = this._config.baseApiPath + '/';
230
181
 
231
- if (data && data.version) {
232
- apiPath = this.getApiPath({version: data.version, type: data.versionType});
182
+ if (data.type && ['admin', 'content'].includes(data.type)) {
183
+ apiPath += data.type;
184
+ } else {
185
+ apiPath += this._config.defaultApiType;
233
186
  }
234
187
 
188
+ // Ensure we end with a trailing slash
189
+ apiPath += '/';
190
+
235
191
  if (absolute) {
236
- urlPath = urlPath.replace(/\/$/, '') + apiPath;
192
+ urlPath = this.urlJoin(adminUrl, apiPath);
237
193
  } else {
238
194
  urlPath = apiPath;
239
195
  }
@@ -248,7 +204,7 @@ module.exports = class UrlUtils {
248
204
  return urlPath;
249
205
  }
250
206
 
251
- return this.createUrl(urlPath, absolute, secure);
207
+ return this.createUrl(urlPath, absolute);
252
208
  }
253
209
 
254
210
  redirect301(res, redirectUrl) {
@@ -257,7 +213,7 @@ module.exports = class UrlUtils {
257
213
  }
258
214
 
259
215
  redirectToAdmin(status, res, adminPath) {
260
- var redirectUrl = this.urlJoin(this.urlFor('admin', true), adminPath, '/');
216
+ let redirectUrl = this.urlJoin(this.urlFor('admin', true), adminPath, '/');
261
217
 
262
218
  if (status === 301) {
263
219
  return this.redirect301(res, redirectUrl);
@@ -3,8 +3,6 @@ module.exports = {
3
3
  absoluteToTransformReady: require('./absolute-to-transform-ready'),
4
4
  deduplicateDoubleSlashes: require('./deduplicate-double-slashes'),
5
5
  deduplicateSubdirectory: require('./deduplicate-subdirectory'),
6
- getApiPath: require('./get-api-path'),
7
- getVersionPath: require('./get-version-path'),
8
6
  htmlAbsoluteToRelative: require('./html-absolute-to-relative'),
9
7
  htmlRelativeToAbsolute: require('./html-relative-to-absolute'),
10
8
  htmlAbsoluteToTransformReady: require('./html-absolute-to-transform-ready'),
package/package.json CHANGED
@@ -1,29 +1,30 @@
1
1
  {
2
2
  "name": "@tryghost/url-utils",
3
- "version": "2.1.0",
3
+ "version": "4.0.0",
4
4
  "repository": "https://github.com/TryGhost/SDK/tree/master/packages/url-utils",
5
5
  "author": "Ghost Foundation",
6
6
  "license": "MIT",
7
- "main": "lib/index.js",
7
+ "main": "index.js",
8
8
  "scripts": {
9
9
  "dev": "echo \"Implement me!\"",
10
- "test": "NODE_ENV=testing c8 --all --reporter text --reporter cobertura mocha './test/**/*.test.js'",
10
+ "test": "NODE_ENV=testing c8 --all --reporter text --reporter cobertura --reporter html mocha './test/**/*.test.js'",
11
11
  "lint": "eslint . --ext .js --cache",
12
12
  "posttest": "yarn lint"
13
13
  },
14
14
  "files": [
15
- "lib/"
15
+ "lib/",
16
+ "index.js"
16
17
  ],
17
18
  "publishConfig": {
18
19
  "access": "public"
19
20
  },
20
21
  "devDependencies": {
21
- "@tryghost/config-url-helpers": "0.1.5",
22
- "c8": "7.11.0",
23
- "mocha": "7.2.0",
24
- "rewire": "5.0.0",
22
+ "@tryghost/config-url-helpers": "1.0.0",
23
+ "c8": "7.11.2",
24
+ "mocha": "10.0.0",
25
+ "rewire": "6.0.0",
25
26
  "should": "13.2.3",
26
- "sinon": "9.2.4"
27
+ "sinon": "14.0.0"
27
28
  },
28
29
  "dependencies": {
29
30
  "cheerio": "^0.22.0",
@@ -33,5 +34,5 @@
33
34
  "remark-footnotes": "^1.0.0",
34
35
  "unist-util-visit": "^2.0.0"
35
36
  },
36
- "gitHead": "8bfb11a7576f3a09aa2a4d633933bb8f341d9329"
37
+ "gitHead": "76ea47794eb7eb1e2b6e9d5b68d52653efc5b85a"
37
38
  }
@@ -1,18 +0,0 @@
1
- const getVersionPath = require('./get-version-path');
2
-
3
- /**
4
- * Returns API path combining base path and path for specific version/type
5
- * @param {Object} options
6
- * @param {string} options.version (v2, v3, v4, canary, etc)
7
- * @param {string} options.type (admin, content, members)
8
- * @param {string} options.baseApiPath
9
- * @param {Object} options.apiVersions
10
- * @return {string} API Path for version
11
- */
12
- function getApiPath(options) {
13
- const versionPath = getVersionPath(options);
14
-
15
- return `${options.baseApiPath}${versionPath}`;
16
- }
17
-
18
- module.exports = getApiPath;
@@ -1,20 +0,0 @@
1
- /**
2
- * Returns API path combining base path and path for specific version/type
3
- * @param {Object} options
4
- * @param {string} options.version (v2, v3, canary, etc)
5
- * @param {string} options.type (admin, content, members)
6
- * @param {Object} options.apiVersions
7
- * @return {string} API Path for version
8
- */
9
- function getVersionPath(options) {
10
- let {version, type} = options;
11
- let versionData = options.apiVersions[version];
12
-
13
- if (typeof versionData === 'string') {
14
- versionData = options.apiVersions[versionData];
15
- }
16
-
17
- return `/${versionData[type]}/`;
18
- }
19
-
20
- module.exports = getVersionPath;