Skip to content

Commit 8882eb4

Browse files
committed
Added Types to Simple Utility Functions
- This adds types to simple utilities with no dependencies on other utils
1 parent 3ae53e0 commit 8882eb4

File tree

8 files changed

+89
-44
lines changed

8 files changed

+89
-44
lines changed
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
// @ts-nocheck
2-
function deduplicateDoubleSlashes(url) {
1+
function deduplicateDoubleSlashes(url: string): string {
32
return url.replace(/\/\//g, '/');
43
}
54

5+
export default deduplicateDoubleSlashes;
66
module.exports = deduplicateDoubleSlashes;

packages/url-utils/src/utils/deduplicate-subdirectory.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
// @ts-nocheck
2-
const {URL} = require('url');
1+
import {URL} from 'url';
32

43
/**
54
* Remove duplicated directories from the start of a path or url's path
@@ -8,7 +7,7 @@ const {URL} = require('url');
87
* @param {string} rootUrl Root URL with an optional subdirectory
98
* @returns {string} URL or pathname with any duplicated subdirectory removed
109
*/
11-
const deduplicateSubdirectory = function deduplicateSubdirectory(url, rootUrl) {
10+
const deduplicateSubdirectory = function deduplicateSubdirectory(url: string, rootUrl: string): string {
1211
// force root url to always have a trailing-slash for consistent behaviour
1312
if (!rootUrl.endsWith('/')) {
1413
rootUrl = `${rootUrl}/`;
@@ -29,4 +28,5 @@ const deduplicateSubdirectory = function deduplicateSubdirectory(url, rootUrl) {
2928
return url.replace(subdirRegex, `$1${subdir}/`);
3029
};
3130

31+
export default deduplicateSubdirectory;
3232
module.exports = deduplicateSubdirectory;

packages/url-utils/src/utils/index.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,22 @@
11
// @ts-nocheck
2+
import deduplicateDoubleSlashes from './deduplicate-double-slashes';
3+
import deduplicateSubdirectory from './deduplicate-subdirectory';
4+
import isSSL from './is-ssl';
5+
import replacePermalink from './replace-permalink';
6+
import stripSubdirectoryFromPath from './strip-subdirectory-from-path';
7+
import urlJoin from './url-join';
8+
29
module.exports = {
310
absoluteToRelative: require('./absolute-to-relative'),
411
absoluteToTransformReady: require('./absolute-to-transform-ready'),
5-
deduplicateDoubleSlashes: require('./deduplicate-double-slashes'),
6-
deduplicateSubdirectory: require('./deduplicate-subdirectory'),
12+
deduplicateDoubleSlashes,
13+
deduplicateSubdirectory,
714
htmlAbsoluteToRelative: require('./html-absolute-to-relative'),
815
htmlRelativeToAbsolute: require('./html-relative-to-absolute'),
916
htmlAbsoluteToTransformReady: require('./html-absolute-to-transform-ready'),
1017
htmlRelativeToTransformReady: require('./html-relative-to-transform-ready'),
1118
htmlToTransformReady: require('./html-to-transform-ready'),
12-
isSSL: require('./is-ssl'),
19+
isSSL,
1320
markdownAbsoluteToRelative: require('./markdown-absolute-to-relative'),
1421
markdownRelativeToAbsolute: require('./markdown-relative-to-absolute'),
1522
markdownAbsoluteToTransformReady: require('./markdown-absolute-to-transform-ready'),
@@ -30,10 +37,10 @@ module.exports = {
3037
plaintextToTransformReady: require('./plaintext-to-transform-ready'),
3138
relativeToAbsolute: require('./relative-to-absolute'),
3239
relativeToTransformReady: require('./relative-to-transform-ready'),
33-
replacePermalink: require('./replace-permalink'),
34-
stripSubdirectoryFromPath: require('./strip-subdirectory-from-path'),
40+
replacePermalink,
41+
stripSubdirectoryFromPath,
3542
toTransformReady: require('./to-transform-ready'),
3643
transformReadyToAbsolute: require('./transform-ready-to-absolute'),
3744
transformReadyToRelative: require('./transform-ready-to-relative'),
38-
urlJoin: require('./url-join')
45+
urlJoin
3946
};
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
// @ts-nocheck
21
// require the whatwg compatible URL library (same behaviour in node and browser)
3-
const {URL} = require('url');
2+
import {URL} from 'url';
43

5-
function isSSL(urlToParse) {
4+
function isSSL(urlToParse: string): boolean {
65
const {protocol} = new URL(urlToParse);
76
return protocol === 'https:';
87
}
98

9+
export default isSSL;
1010
module.exports = isSSL;

packages/url-utils/src/utils/relative-to-absolute.ts

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
// @ts-nocheck
21
// require the whatwg compatible URL library (same behaviour in node and browser)
3-
const {URL} = require('url');
4-
const urlJoin = require('./url-join');
2+
import {URL} from 'url';
3+
import urlJoin from './url-join';
54

65
// NOTE: Ghost's relative->absolute handling is a little strange when the rootUrl
76
// includes a subdirectory. Root-relative paths such as /content/image.jpg are
@@ -12,6 +11,12 @@ const urlJoin = require('./url-join');
1211
// this when all root-relative paths are treated as subdir-relative we have to
1312
// rely on subdirectory deduplication.
1413

14+
interface RelativeToAbsoluteOptions {
15+
assetsOnly?: boolean;
16+
staticImageUrlPrefix?: string;
17+
secure?: boolean;
18+
}
19+
1520
/**
1621
* Convert a root-relative path to an absolute URL based on the supplied root.
1722
* Will _only_ convert root-relative urls (/some/path not some/path)
@@ -22,24 +27,36 @@ const urlJoin = require('./url-join');
2227
* @param {object} options
2328
* @returns {string} The passed in url or an absolute URL using
2429
*/
25-
const relativeToAbsolute = function relativeToAbsolute(path, rootUrl, itemPath, _options) {
30+
const relativeToAbsolute = function relativeToAbsolute(
31+
path: string,
32+
rootUrl: string,
33+
itemPath?: string | RelativeToAbsoluteOptions | null,
34+
_options?: RelativeToAbsoluteOptions
35+
): string {
2636
// itemPath is optional, if it's an object it may be the options param instead
27-
if (typeof itemPath === 'object' && !_options) {
28-
_options = itemPath;
29-
itemPath = null;
37+
let actualItemPath: string | null = null;
38+
let actualOptions: RelativeToAbsoluteOptions;
39+
40+
if (itemPath && typeof itemPath === 'object' && !_options) {
41+
actualOptions = itemPath;
42+
actualItemPath = null;
43+
} else {
44+
actualOptions = _options || {};
45+
actualItemPath = typeof itemPath === 'string' ? itemPath : null;
3046
}
3147

3248
// itemPath could be sent as a full url in which case, extract the pathname
33-
if (itemPath && itemPath.match(/^http/)) {
34-
const itemUrl = new URL(itemPath);
35-
itemPath = itemUrl.pathname;
49+
if (actualItemPath && actualItemPath.match(/^http/)) {
50+
const itemUrl = new URL(actualItemPath);
51+
actualItemPath = itemUrl.pathname;
3652
}
3753

38-
const defaultOptions = {
54+
const defaultOptions: Required<RelativeToAbsoluteOptions> = {
3955
assetsOnly: false,
40-
staticImageUrlPrefix: 'content/images'
56+
staticImageUrlPrefix: 'content/images',
57+
secure: false
4158
};
42-
const options = Object.assign({}, defaultOptions, _options);
59+
const options = Object.assign({}, defaultOptions, actualOptions);
4360

4461
// return the path as-is if it's not an asset path and we're only modifying assets
4562
if (options.assetsOnly) {
@@ -81,7 +98,7 @@ const relativeToAbsolute = function relativeToAbsolute(path, rootUrl, itemPath,
8198
}
8299

83100
const parsedRootUrl = new URL(rootUrl);
84-
const basePath = path.startsWith('/') ? '' : itemPath;
101+
const basePath = path.startsWith('/') ? '' : (actualItemPath || '');
85102
const fullPath = urlJoin([parsedRootUrl.pathname, basePath, path], {rootUrl});
86103
const absoluteUrl = new URL(fullPath, rootUrl);
87104

@@ -92,4 +109,5 @@ const relativeToAbsolute = function relativeToAbsolute(path, rootUrl, itemPath,
92109
return absoluteUrl.toString();
93110
};
94111

112+
export default relativeToAbsolute;
95113
module.exports = relativeToAbsolute;
Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,25 @@
1-
// @ts-nocheck
2-
const moment = require('moment-timezone');
1+
import moment from 'moment-timezone';
2+
3+
interface PermalinkResource {
4+
published_at?: string | number | Date;
5+
primary_author?: {
6+
slug: string;
7+
};
8+
primary_tag?: {
9+
slug: string;
10+
};
11+
slug: string;
12+
id: string | number;
13+
}
314

415
/**
516
* creates the url path for a post based on blog timezone and permalink pattern
617
*/
7-
function replacePermalink(permalink, resource, timezone = 'UTC') {
18+
function replacePermalink(permalink: string, resource: PermalinkResource, timezone: string = 'UTC'): string {
819
const output = permalink;
920
const primaryTagFallback = 'all';
1021
const publishedAtMoment = moment.tz(resource.published_at || Date.now(), timezone);
11-
const permalinkLookUp = {
22+
const permalinkLookUp: Record<string, () => string> = {
1223
year: function () {
1324
return publishedAtMoment.format('YYYY');
1425
},
@@ -19,7 +30,7 @@ function replacePermalink(permalink, resource, timezone = 'UTC') {
1930
return publishedAtMoment.format('DD');
2031
},
2132
author: function () {
22-
return resource.primary_author.slug;
33+
return resource.primary_author!.slug;
2334
},
2435
primary_author: function () {
2536
return resource.primary_author ? resource.primary_author.slug : primaryTagFallback;
@@ -31,17 +42,22 @@ function replacePermalink(permalink, resource, timezone = 'UTC') {
3142
return resource.slug;
3243
},
3344
id: function () {
34-
return resource.id;
45+
return String(resource.id);
3546
}
3647
};
3748

3849
// replace tags like :slug or :year with actual values
3950
const permalinkKeys = Object.keys(permalinkLookUp);
40-
return output.replace(/(:[a-z_]+)/g, function (match) {
41-
if (permalinkKeys.includes(match.substr(1))) {
42-
return permalinkLookUp[match.substr(1)]();
51+
return output.replace(/(:[a-z_]+)/g, function (match: string): string {
52+
const key = match.substr(1);
53+
if (permalinkKeys.includes(key)) {
54+
// Known route segment - use the lookup function
55+
return permalinkLookUp[key]();
4356
}
57+
// Unknown route segment - return 'undefined' string
58+
return 'undefined';
4459
});
4560
}
4661

62+
export default replacePermalink;
4763
module.exports = replacePermalink;

packages/url-utils/src/utils/strip-subdirectory-from-path.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
// @ts-nocheck
2-
const {URL} = require('url');
1+
import {URL} from 'url';
32

43
/**
54
* Removes the directory in the root url from the relative path
@@ -8,13 +7,13 @@ const {URL} = require('url');
87
* @param {string} rootUrl Root URL (eg, 'https://mysite.com/my/subdir/)
98
* @returns {string} Path relative to the rootUrl's path
109
*/
11-
const stripSubdirectoryFromPath = function stripSubdirectoryFromPath(path = '', rootUrl = '') {
10+
const stripSubdirectoryFromPath = function stripSubdirectoryFromPath(path: string = '', rootUrl: string = ''): string {
1211
// force root to always have a trailing-slash for consistent behaviour
1312
if (!rootUrl.endsWith('/')) {
1413
rootUrl = `${rootUrl}/`;
1514
}
1615

17-
let parsedRoot;
16+
let parsedRoot: URL;
1817

1918
try {
2019
parsedRoot = new URL(rootUrl);
@@ -34,4 +33,5 @@ const stripSubdirectoryFromPath = function stripSubdirectoryFromPath(path = '',
3433
return path;
3534
};
3635

36+
export default stripSubdirectoryFromPath;
3737
module.exports = stripSubdirectoryFromPath;

packages/url-utils/src/utils/url-join.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1-
// @ts-nocheck
2-
const deduplicateSubdirectory = require('./deduplicate-subdirectory');
1+
import deduplicateSubdirectory from './deduplicate-subdirectory';
2+
3+
interface UrlJoinOptions {
4+
rootUrl: string;
5+
}
36

47
/** urlJoin
58
* Returns a URL/path for internal use in Ghost.
@@ -8,7 +11,7 @@ const deduplicateSubdirectory = require('./deduplicate-subdirectory');
811
* @param {string} options.rootUrl used for deduplicating any subdirectories
912
* @return {string} URL concatinated URL/path of arguments.
1013
*/
11-
function urlJoin(parts, options) {
14+
function urlJoin(parts: string[], options: UrlJoinOptions): string {
1215
let prefixDoubleSlash = false;
1316

1417
// Remove empty item at the beginning
@@ -35,4 +38,5 @@ function urlJoin(parts, options) {
3538
return deduplicateSubdirectory(url, options.rootUrl);
3639
}
3740

41+
export default urlJoin;
3842
module.exports = urlJoin;

0 commit comments

Comments
 (0)