Skip to content

Commit 076eb91

Browse files
committed
refactor: Replace flow with type-check and docs
1 parent 11d65ba commit 076eb91

21 files changed

+471
-381
lines changed

.babelrc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
"es2015"
44
],
55
"plugins": [
6-
"transform-runtime",
7-
"transform-flow-strip-types"
6+
"transform-runtime"
87
],
98
"env": {
109
"test": {

lib/contentful.js

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
/* @flow */
2-
31
/**
42
* Contentful CDA SDK. Allows you to create instances of a client with access
53
* to the Contentful Content Delivery API.
@@ -8,17 +6,17 @@
86

97
import createHttpClient from './create-http-client'
108
import createCdaApi from './create-cda-api'
11-
import type {ContentfulClient} from './create-cda-api'
9+
import {typeCheck} from './type-check'
1210

13-
type ClientParams = {
14-
space: string,
15-
accessToken: string,
16-
insecure?: boolean,
17-
host?: string,
18-
resolveLinks?: boolean,
19-
agent?: Object,
20-
headers?: Object
21-
}
11+
const ClientParams = `{
12+
space: String,
13+
accessToken: String,
14+
insecure: Maybe Boolean,
15+
host: Maybe String,
16+
resolveLinks: Maybe Boolean,
17+
agent: Maybe Object,
18+
headers: Maybe Object
19+
}`
2220

2321
/**
2422
* Create a client instance
@@ -39,7 +37,7 @@ type ClientParams = {
3937
* space: 'mySpaceId'
4038
* })
4139
*/
42-
export default function createClient (axios: Object, params: ClientParams) : ContentfulClient {
40+
export default function createClient (axios, params) {
4341
if (!params.accessToken) {
4442
throw new TypeError('Expected parameter accessToken')
4543
}
@@ -48,6 +46,8 @@ export default function createClient (axios: Object, params: ClientParams) : Con
4846
throw new TypeError('Expected parameter space')
4947
}
5048

49+
typeCheck(ClientParams, params)
50+
5151
// Use resolveLinks param if specified, otherwise default to true
5252
const resolveLinks = !!('resolveLinks' in params ? params.resolveLinks : true)
5353

lib/create-cda-api.js

Lines changed: 22 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
/* @flow */
2-
31
/**
42
* Contentful CDA API
53
* @namespace CDAClient
@@ -9,36 +7,10 @@
97
* @namespace Entities
108
*/
119

12-
/**
13-
* Link to another entity. See <a href="https://www.contentful.com/developers/docs/concepts/links/">Links</a> for more details.
14-
* @memberof Entities
15-
* @typedef Link
16-
* @prop {string} type - type of this entity. Always link.
17-
* @prop {string} id
18-
* @prop {string} linkType - type of this link. If defined, either Entry or Asset
19-
*/
20-
21-
/**
22-
* System metadata. See <a href="https://www.contentful.com/developers/docs/references/content-delivery-api/#/introduction/common-resource-attributes">Common Resource Attributes</a> for more details.
23-
* @memberof Entities
24-
* @typedef Sys
25-
* @prop {string} type
26-
* @prop {string} id
27-
* @prop {Entities.Link} space
28-
* @prop {string} createdAt
29-
* @prop {string} updatedAt
30-
* @prop {number} revision
31-
*/
32-
33-
import type {Space} from './entities/space'
3410
import {wrapSpace} from './entities/space'
35-
import type {ContentType, ContentTypeCollection} from './entities/content-type'
3611
import {wrapContentType, wrapContentTypeCollection} from './entities/content-type'
37-
import type {Entry, EntryCollection} from './entities/entry'
3812
import {wrapEntry, wrapEntryCollection} from './entities/entry'
39-
import type {Asset, AssetCollection} from './entities/asset'
4013
import {wrapAsset, wrapAssetCollection} from './entities/asset'
41-
import type {SyncCollection} from './sync'
4214
import pagedSync from './sync'
4315
import createRequestConfig from './create-request-config'
4416

@@ -54,33 +26,32 @@ import createRequestConfig from './create-request-config'
5426
* @prop {function} getAssets
5527
* @prop {function} sync
5628
*/
57-
export type ContentfulClient = {
58-
getSpace: (id: string) => Promise<Space>,
59-
getContentType: (id: string) => Promise<ContentType>,
60-
getContentTypes: (query?: Object) => Promise<ContentTypeCollection>,
61-
getEntry: (id: string) => Promise<Entry>,
62-
getEntries: (query?: Object) => Promise<EntryCollection>,
63-
getAsset: (id: string) => Promise<Asset>,
64-
getAssets: (query?: Object) => Promise<AssetCollection>,
65-
sync: (query: Object) => Promise<SyncCollection>
66-
}
67-
function errorHandler (error: Object) {
29+
function errorHandler (error) {
6830
if (error.data) {
6931
throw error.data
7032
}
7133
throw error
7234
}
7335

7436
/**
75-
* @private
7637
* Link resolution can be turned off for the methods that use it, or it can
7738
* be turned off globally. The local setting overrides the global setting.
39+
* @private
40+
* @param {Object} query - regular query object used for collection endpoints
41+
* @param {boolean} globalSetting - Global library setting for link resolution
7842
*/
79-
function shouldLinksResolve (query: Object, globalSetting: boolean): boolean {
43+
function shouldLinksResolve (query, globalSetting) {
8044
return !!('resolveLinks' in query ? query.resolveLinks : globalSetting)
8145
}
8246

83-
export default function createCdaApi (http: Object, resolveLinksGlobalSetting: boolean): ContentfulClient {
47+
/**
48+
* Creates CDA API object
49+
* @private
50+
* @param {Object} http - HTTP client instance
51+
* @param {boolean} resolveLinksGlobalSetting - Global library setting for link resolution
52+
* @return {ClientAPI}
53+
*/
54+
export default function createCdaApi (http, resolveLinksGlobalSetting) {
8455
/**
8556
* Gets the Space which the client is currently configured to use
8657
* @memberof CDAClient
@@ -89,7 +60,7 @@ export default function createCdaApi (http: Object, resolveLinksGlobalSetting: b
8960
* client.getSpace()
9061
* .then(space => console.log(space))
9162
*/
92-
function getSpace (): Promise<Space> {
63+
function getSpace () {
9364
return http.get('')
9465
.then(response => wrapSpace(response.data), errorHandler)
9566
}
@@ -103,21 +74,21 @@ export default function createCdaApi (http: Object, resolveLinksGlobalSetting: b
10374
* client.getContentType('contentTypeId')
10475
* .then(contentType => console.log(contentType))
10576
*/
106-
function getContentType (id: string): Promise<ContentType> {
77+
function getContentType (id) {
10778
return http.get('content_types/' + id)
10879
.then(response => wrapContentType(response.data), errorHandler)
10980
}
11081

11182
/**
11283
* Gets a collection of Content Types
11384
* @memberof CDAClient
114-
* @param {Entities.Query} query
85+
* @param {Entities.Query=} query - Query object
11586
* @return {Promise<Entities.ContentTypeCollection>} Promise for a collection of Content Types
11687
* @example
11788
* client.getContentTypes()
11889
* .then(contentTypes => console.log(contentTypes.items))
11990
*/
120-
function getContentTypes (query?: Object = {}): Promise<ContentTypeCollection> {
91+
function getContentTypes (query = {}) {
12192
return http.get('content_types', createRequestConfig({query: query}))
12293
.then(response => wrapContentTypeCollection(response.data), errorHandler)
12394
}
@@ -131,7 +102,7 @@ export default function createCdaApi (http: Object, resolveLinksGlobalSetting: b
131102
* client.getEntry('entryId')
132103
* .then(entry => console.log(entry))
133104
*/
134-
function getEntry (id: string): Promise<Entry> {
105+
function getEntry (id) {
135106
return http.get('entries/' + id)
136107
.then(response => wrapEntry(response.data), errorHandler)
137108
}
@@ -146,7 +117,7 @@ export default function createCdaApi (http: Object, resolveLinksGlobalSetting: b
146117
* client.getEntries({content_type: 'contentTypeId'})
147118
* .then(entries => console.log(entries.items))
148119
*/
149-
function getEntries (query?: Object = {}): Promise<EntryCollection> {
120+
function getEntries (query = {}) {
150121
const resolveLinks = shouldLinksResolve(query, resolveLinksGlobalSetting)
151122
return http.get('entries', createRequestConfig({query: query}))
152123
.then(response => wrapEntryCollection(response.data, resolveLinks), errorHandler)
@@ -161,7 +132,7 @@ export default function createCdaApi (http: Object, resolveLinksGlobalSetting: b
161132
* client.getAsset('assetId')
162133
* .then(asset => console.log(asset))
163134
*/
164-
function getAsset (id: string): Promise<Asset> {
135+
function getAsset (id) {
165136
return http.get('assets/' + id)
166137
.then(response => wrapAsset(response.data), errorHandler)
167138
}
@@ -175,7 +146,7 @@ export default function createCdaApi (http: Object, resolveLinksGlobalSetting: b
175146
* client.getAssets()
176147
* .then(assets => console.log(assets.items))
177148
*/
178-
function getAssets (query?: Object = {}): Promise<AssetCollection> {
149+
function getAssets (query = {}) {
179150
return http.get('assets', createRequestConfig({query: query}))
180151
.then(response => wrapAssetCollection(response.data), errorHandler)
181152
}
@@ -195,7 +166,7 @@ export default function createCdaApi (http: Object, resolveLinksGlobalSetting: b
195166
* client.sync()
196167
* .then(response => console.log(response.entries, response.assets, response.nextSyncToken))
197168
*/
198-
function sync (query?: Object = {}): Promise<SyncCollection> {
169+
function sync (query = {}) {
199170
const resolveLinks = shouldLinksResolve(query, resolveLinksGlobalSetting)
200171
return pagedSync(http, query, resolveLinks)
201172
}

lib/create-http-client.js

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,20 @@
1-
/* @flow */
21
import qs from 'querystring'
32
import version from '../version'
43

5-
type HttpClientParams = {
6-
space: string,
7-
accessToken: string,
8-
insecure?: boolean,
9-
host?: string,
10-
agent?: Object,
11-
headers?: Object
12-
}
13-
144
/**
15-
* @private
165
* Create pre configured axios instance
6+
* @private
7+
* @param {Object} axios - Axios library
8+
* @param {Object} HTTPClientParams - Initialization parameters for the HTTP client
9+
* @prop {string} space - Space ID
10+
* @prop {string} accessToken - Access Token
11+
* @prop {boolean=} insecure - If we should use http instead
12+
* @prop {string=} host - Alternate host
13+
* @prop {Object=} agent - HTTP agent for node
14+
* @prop {Object=} headers - Additional headers
15+
* @return {Object} Initialized axios instance
1716
*/
18-
export default function createHttpClient (axios: Object, {space, accessToken, insecure, host, agent, headers}: HttpClientParams): Object {
17+
export default function createHttpClient (axios, {space, accessToken, insecure, host, agent, headers}) {
1918
let [hostname, port] = (host && host.split(':')) || []
2019
hostname = hostname || 'cdn.contentful.com'
2120
port = port || (insecure ? 80 : 443)

lib/create-request-config.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
1-
/* @flow */
21
import {cloneDeep} from 'lodash/lang'
32

4-
export default function createRequestConfig ({query}: {query: Object}): {params: Object} {
3+
/**
4+
* Creates request parameters configuration by parsing an existing query object
5+
* @private
6+
* @param {Object} query
7+
* @return {Object} Config object with `params` property, ready to be used in axios
8+
*/
9+
export default function createRequestConfig ({query}) {
510
const config = {}
611
delete query.resolveLinks
712
config.params = cloneDeep(query)

lib/entities/asset.js

Lines changed: 31 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,9 @@
1-
/* @flow */
1+
import {typeCheck} from '../type-check'
22
import {cloneDeep} from 'lodash/lang'
3-
import type {Sys} from './sys'
4-
import type {Field} from './field'
3+
import {SysProps} from './sys'
4+
import Field from './field'
55
import mixinToPlainObject from '../mixins/to-plain-object'
66

7-
type AssetResponse = {
8-
sys: Sys & {
9-
locale: string
10-
},
11-
fields: { [key: string]: Field }
12-
}
13-
147
/**
158
* @memberof Entities
169
* @typedef Asset
@@ -26,21 +19,24 @@ type AssetResponse = {
2619
* @prop {Object} fields.file.details - Details for the file, depending on file type (example: image size in bytes, etc)
2720
* @prop {function(): Object} toPlainObject() - Returns this Asset as a plain JS object
2821
*/
29-
export type Asset = {
30-
sys: Sys & {
31-
locale: string
22+
const Asset = `{
23+
sys: {
24+
${SysProps},
25+
locale: String
3226
},
33-
fields: { [key: string]: Field },
34-
toPlainObject: () => Object
35-
}
27+
fields: Field
28+
}`
3629

37-
export type DeletedAsset = Asset
30+
export default Asset
3831

39-
type AssetCollectionResponse = {
40-
total: number,
41-
skip: number,
42-
limit: number,
43-
items: Array<AssetResponse>
32+
/**
33+
* @private
34+
* @param {Object} data - Raw asset data
35+
* @return {Asset} Wrapped asset data
36+
*/
37+
export function wrapAsset (data) {
38+
typeCheck(Asset, data, [Field])
39+
return Object.freeze(mixinToPlainObject(cloneDeep(data)))
4440
}
4541

4642
/**
@@ -52,18 +48,19 @@ type AssetCollectionResponse = {
5248
* @prop {Array<Entities.Asset>} items
5349
* @prop {function(): Object} toPlainObject() - Returns this Asset collection as a plain JS object
5450
*/
55-
export type AssetCollection = {
56-
total: number,
57-
skip: number,
58-
limit: number,
59-
items: Array<Asset>,
60-
toPlainObject: () => Object
61-
}
62-
63-
export function wrapAsset (data: AssetResponse): Asset {
64-
return Object.freeze(mixinToPlainObject(cloneDeep(data)))
65-
}
51+
const AssetCollection = `{
52+
total: Number,
53+
skip: Number,
54+
limit: Number,
55+
items: [${Asset}]
56+
}`
6657

67-
export function wrapAssetCollection (data: AssetCollectionResponse): AssetCollection {
58+
/**
59+
* @private
60+
* @param {Object} data - Raw asset collection data
61+
* @return {AssetCollection} Wrapped asset collection data
62+
*/
63+
export function wrapAssetCollection (data) {
64+
typeCheck(AssetCollection, data, [Field])
6865
return Object.freeze(mixinToPlainObject(cloneDeep(data)))
6966
}

0 commit comments

Comments
 (0)