Skip to content
This repository was archived by the owner on Oct 10, 2022. It is now read-only.

Commit 76a7ef7

Browse files
committed
Simplify options handling
1 parent 2edd766 commit 76a7ef7

File tree

8 files changed

+93
-102
lines changed

8 files changed

+93
-102
lines changed

.eslintrc.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ module.exports = {
88
'max-nested-callbacks': 0,
99
'max-statements': 0,
1010
'no-await-in-loop': 0,
11-
'no-param-reassign': 0,
1211
'fp/no-class': 0,
1312
'fp/no-let': 0,
1413
'fp/no-loops': 0,

src/deploy/hash_files.js

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,27 @@ const { promisify } = require('util')
33
const walker = require('folder-walker')
44
const pump = promisify(require('pump'))
55

6-
const { DEFAULT_CONCURRENT_HASH } = require('./constants')
76
const { hasherCtor, manifestCollectorCtor, fileFilterCtor, fileNormalizerCtor } = require('./hasher_segments')
87

9-
const hashFiles = async (dir, configPath, opts) => {
10-
opts = {
11-
concurrentHash: DEFAULT_CONCURRENT_HASH,
12-
assetType: 'file',
13-
statusCb: () => {},
14-
...opts,
15-
}
16-
17-
if (!opts.filter) throw new Error('Missing filter function option')
18-
const fileStream = walker([configPath, dir], { filter: opts.filter })
19-
const filter = fileFilterCtor()
20-
const hasher = hasherCtor(opts)
21-
const fileNormalizer = fileNormalizerCtor(opts)
8+
const hashFiles = async (
9+
dir,
10+
configPath,
11+
{ concurrentHash, hashAlgorithm = 'sha1', assetType = 'file', statusCb, filter },
12+
) => {
13+
if (!filter) throw new Error('Missing filter function option')
14+
const fileStream = walker([configPath, dir], { filter })
15+
const fileFilter = fileFilterCtor()
16+
const hasher = hasherCtor({ concurrentHash, hashAlgorithm })
17+
const fileNormalizer = fileNormalizerCtor({ assetType })
2218

2319
// Written to by manifestCollector
2420
// normalizedPath: hash (wanted by deploy API)
2521
const files = {}
2622
// hash: [fileObj, fileObj, fileObj]
2723
const filesShaMap = {}
28-
const manifestCollector = manifestCollectorCtor(files, filesShaMap, opts)
24+
const manifestCollector = manifestCollectorCtor(files, filesShaMap, { statusCb, assetType })
2925

30-
await pump(fileStream, filter, hasher, fileNormalizer, manifestCollector)
26+
await pump(fileStream, fileFilter, hasher, fileNormalizer, manifestCollector)
3127

3228
return { files, filesShaMap }
3329
}

src/deploy/hash_files.test.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,15 @@ const path = require('path')
22

33
const test = require('ava')
44

5+
const { DEFAULT_CONCURRENT_HASH } = require('./constants')
56
const hashFiles = require('./hash_files')
67
const { defaultFilter } = require('./util')
78

89
test('hashes files in a folder', async (t) => {
910
const { files, filesShaMap } = await hashFiles(__dirname, path.resolve(__dirname, '../../fixtures/netlify.toml'), {
1011
filter: defaultFilter,
12+
concurrentHash: DEFAULT_CONCURRENT_HASH,
13+
statusCb() {},
1114
})
1215
t.truthy(files['netlify.toml'], 'includes the netlify.toml file')
1316
Object.keys(files).forEach((filePath) => {

src/deploy/hash_fns.js

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,19 @@ const zipIt = require('@netlify/zip-it-and-ship-it')
55
const fromArray = require('from2-array')
66
const pump = promisify(require('pump'))
77

8-
const { DEFAULT_CONCURRENT_HASH } = require('./constants')
98
const { hasherCtor, manifestCollectorCtor } = require('./hasher_segments')
109

11-
const hashFns = async (dir, opts) => {
12-
opts = {
13-
concurrentHash: DEFAULT_CONCURRENT_HASH,
14-
assetType: 'function',
15-
hashAlgorithm: 'sha256',
16-
// tmpDir,
17-
statusCb: () => {},
18-
...opts,
19-
}
10+
const hashFns = async (dir, { tmpDir, concurrentHash, hashAlgorithm = 'sha256', assetType = 'function', statusCb }) => {
2011
// early out if the functions dir is omitted
2112
if (!dir) return { functions: {}, shaMap: {} }
22-
if (!opts.tmpDir) throw new Error('Missing tmpDir directory for zipping files')
13+
if (!tmpDir) throw new Error('Missing tmpDir directory for zipping files')
2314

24-
const functionZips = await zipIt.zipFunctions(dir, opts.tmpDir)
15+
const functionZips = await zipIt.zipFunctions(dir, tmpDir)
2516

2617
const fileObjs = functionZips.map(({ path: functionPath, runtime }) => ({
2718
filepath: functionPath,
28-
root: opts.tmpDir,
29-
relname: path.relative(opts.tmpDir, functionPath),
19+
root: tmpDir,
20+
relname: path.relative(tmpDir, functionPath),
3021
basename: path.basename(functionPath),
3122
extname: path.extname(functionPath),
3223
type: 'file',
@@ -37,14 +28,14 @@ const hashFns = async (dir, opts) => {
3728

3829
const functionStream = fromArray.obj(fileObjs)
3930

40-
const hasher = hasherCtor(opts)
31+
const hasher = hasherCtor({ concurrentHash, hashAlgorithm })
4132

4233
// Written to by manifestCollector
4334
// normalizedPath: hash (wanted by deploy API)
4435
const functions = {}
4536
// hash: [fileObj, fileObj, fileObj]
4637
const fnShaMap = {}
47-
const manifestCollector = manifestCollectorCtor(functions, fnShaMap, opts)
38+
const manifestCollector = manifestCollectorCtor(functions, fnShaMap, { statusCb, assetType })
4839

4940
await pump(functionStream, hasher, manifestCollector)
5041

src/deploy/hash_fns.test.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
const test = require('ava')
22
const tempy = require('tempy')
33

4+
const { DEFAULT_CONCURRENT_HASH } = require('./constants')
45
const hashFns = require('./hash_fns')
5-
const { defaultFilter } = require('./util')
66

77
test('hashes files in a folder', async (t) => {
8-
const { functions, fnShaMap } = await hashFns(__dirname, { filter: defaultFilter, tmpDir: tempy.directory() })
8+
const { functions, fnShaMap } = await hashFns(__dirname, {
9+
tmpDir: tempy.directory(),
10+
concurrentHash: DEFAULT_CONCURRENT_HASH,
11+
statusCb() {},
12+
})
913

1014
Object.keys(functions).forEach((path) => {
1115
t.truthy(path, 'each file has a path')

src/deploy/hasher_segments.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const map = require('through2-map').obj
77
const { normalizePath } = require('./util')
88

99
// a parallel transform stream segment ctor that hashes fileObj's created by folder-walker
10-
const hasherCtor = ({ concurrentHash, hashAlgorithm = 'sha1' }) => {
10+
const hasherCtor = ({ concurrentHash, hashAlgorithm }) => {
1111
const hashaOpts = { algorithm: hashAlgorithm }
1212
if (!concurrentHash) throw new Error('Missing required opts')
1313
return transform(concurrentHash, { objectMode: true }, async (fileObj, cb) => {
@@ -22,13 +22,14 @@ const hasherCtor = ({ concurrentHash, hashAlgorithm = 'sha1' }) => {
2222
}
2323

2424
// Inject normalized file names into normalizedPath and assetType
25-
const fileNormalizerCtor = ({ assetType = 'file' }) =>
25+
const fileNormalizerCtor = ({ assetType }) =>
2626
map((fileObj) => ({ ...fileObj, assetType, normalizedPath: normalizePath(fileObj.relname) }))
2727

2828
// A writable stream segment ctor that normalizes file paths, and writes shaMap's
2929
const manifestCollectorCtor = (filesObj, shaMap, { statusCb, assetType }) => {
3030
if (!statusCb || !assetType) throw new Error('Missing required options')
3131
return objWriter((fileObj, _, cb) => {
32+
// eslint-disable-next-line no-param-reassign
3233
filesObj[fileObj.normalizedPath] = fileObj.hash
3334

3435
// We map a hash to multiple fileObj's because the same file
@@ -37,6 +38,7 @@ const manifestCollectorCtor = (filesObj, shaMap, { statusCb, assetType }) => {
3738
if (Array.isArray(shaMap[fileObj.hash])) {
3839
shaMap[fileObj.hash].push(fileObj)
3940
} else {
41+
// eslint-disable-next-line no-param-reassign
4042
shaMap[fileObj.hash] = [fileObj]
4143
}
4244
statusCb({

src/deploy/index.js

Lines changed: 35 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,24 @@ const hashFns = require('./hash_fns')
1616
const uploadFiles = require('./upload_files')
1717
const { waitForDiff, waitForDeploy, getUploadList, defaultFilter } = require('./util')
1818

19-
const deploySite = async (api, siteId, dir, opts) => {
20-
opts = {
21-
fnDir: null,
22-
configPath: null,
23-
draft: false,
19+
const deploySite = async (
20+
api,
21+
siteId,
22+
dir,
23+
{
24+
fnDir = null,
25+
configPath = null,
26+
draft = false,
2427
// API calls this the 'title'
25-
message: undefined,
26-
tmpDir: tempy.directory(),
27-
deployTimeout: DEFAULT_DEPLOY_TIMEOUT,
28-
concurrentHash: DEFAULT_CONCURRENT_HASH,
29-
concurrentUpload: DEFAULT_CONCURRENT_UPLOAD,
30-
filter: defaultFilter,
31-
syncFileLimit: DEFAULT_SYNC_LIMIT,
32-
maxRetry: DEFAULT_MAX_RETRY,
33-
statusCb: () => {
28+
message: title,
29+
tmpDir = tempy.directory(),
30+
deployTimeout = DEFAULT_DEPLOY_TIMEOUT,
31+
concurrentHash = DEFAULT_CONCURRENT_HASH,
32+
concurrentUpload = DEFAULT_CONCURRENT_UPLOAD,
33+
filter = defaultFilter,
34+
syncFileLimit = DEFAULT_SYNC_LIMIT,
35+
maxRetry = DEFAULT_MAX_RETRY,
36+
statusCb = () => {
3437
/* default to noop */
3538
// statusObj: {
3639
// type: name-of-step
@@ -39,22 +42,21 @@ const deploySite = async (api, siteId, dir, opts) => {
3942
// spinner: a spinner from cli-spinners package
4043
// }
4144
},
42-
// allows updating an existing deploy
43-
deployId: null,
44-
...opts,
45-
}
46-
47-
const { fnDir, configPath, statusCb, message: title } = opts
48-
45+
deployId: deployIdOpt = null,
46+
hashAlgorithm,
47+
assetType,
48+
branch,
49+
} = {},
50+
) => {
4951
statusCb({
5052
type: 'hashing',
5153
msg: `Hashing files...`,
5254
phase: 'start',
5355
})
5456

5557
const [{ files, filesShaMap }, { functions, fnShaMap }] = await Promise.all([
56-
hashFiles(dir, configPath, opts),
57-
hashFns(fnDir, opts),
58+
hashFiles(dir, configPath, { concurrentHash, hashAlgorithm, assetType, statusCb, filter }),
59+
hashFns(fnDir, { tmpDir, concurrentHash, hashAlgorithm, statusCb, assetType }),
5860
])
5961

6062
const filesCount = Object.keys(files).length
@@ -82,22 +84,22 @@ const deploySite = async (api, siteId, dir, opts) => {
8284
body: {
8385
files,
8486
functions,
85-
async: Object.keys(files).length > opts.syncFileLimit,
86-
branch: opts.branch,
87-
draft: opts.draft,
87+
async: Object.keys(files).length > syncFileLimit,
88+
branch,
89+
draft,
8890
},
8991
})
90-
if (opts.deployId === null) {
92+
if (deployIdOpt === null) {
9193
if (title) {
9294
deployParams = { ...deployParams, title }
9395
}
9496
deploy = await api.createSiteDeploy(deployParams)
9597
} else {
96-
deployParams = { ...deployParams, deploy_id: opts.deployId }
98+
deployParams = { ...deployParams, deploy_id: deployIdOpt }
9799
deploy = await api.updateSiteDeploy(deployParams)
98100
}
99101

100-
if (deployParams.body.async) deploy = await waitForDiff(api, deploy.id, siteId, opts.deployTimeout)
102+
if (deployParams.body.async) deploy = await waitForDiff(api, deploy.id, siteId, deployTimeout)
101103

102104
const { id: deployId, required: requiredFiles, required_functions: requiredFns } = deploy
103105

@@ -111,22 +113,22 @@ const deploySite = async (api, siteId, dir, opts) => {
111113

112114
const uploadList = getUploadList(requiredFiles, filesShaMap).concat(getUploadList(requiredFns, fnShaMap))
113115

114-
await uploadFiles(api, deployId, uploadList, opts)
116+
await uploadFiles(api, deployId, uploadList, { concurrentUpload, statusCb, maxRetry })
115117

116118
statusCb({
117119
type: 'wait-for-deploy',
118120
msg: 'Waiting for deploy to go live...',
119121
phase: 'start',
120122
})
121-
deploy = await waitForDeploy(api, deployId, siteId, opts.deployTimeout)
123+
deploy = await waitForDeploy(api, deployId, siteId, deployTimeout)
122124

123125
statusCb({
124126
type: 'wait-for-deploy',
125-
msg: opts.draft ? 'Draft deploy is live!' : 'Deploy is live!',
127+
msg: draft ? 'Draft deploy is live!' : 'Deploy is live!',
126128
phase: 'stop',
127129
})
128130

129-
await rimraf(opts.tmpDir)
131+
await rimraf(tmpDir)
130132

131133
const deployManifest = {
132134
deployId,

src/index.js

Lines changed: 26 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -6,38 +6,30 @@ const { getMethods } = require('./methods')
66
const { getOperations } = require('./operations')
77

88
class NetlifyAPI {
9-
constructor(accessToken, opts) {
9+
constructor(firstArg, secondArg) {
1010
// variadic arguments
11-
if (typeof accessToken === 'object') {
12-
opts = accessToken
13-
accessToken = null
14-
}
15-
// default opts
16-
opts = {
17-
userAgent: 'netlify/js-client',
18-
scheme: dfn.schemes[0],
19-
host: dfn.host,
20-
pathPrefix: dfn.basePath,
21-
accessToken,
22-
globalParams: {},
23-
...opts,
24-
}
11+
const [accessTokenInput, opts = {}] = typeof firstArg === 'object' ? [null, firstArg] : [firstArg, secondArg]
2512

26-
this.defaultHeaders = {
27-
'User-agent': opts.userAgent,
13+
// default opts
14+
const {
15+
userAgent = 'netlify/js-client',
16+
scheme = dfn.schemes[0],
17+
host = dfn.host,
18+
pathPrefix = dfn.basePath,
19+
accessToken = accessTokenInput,
20+
globalParams = {},
21+
agent,
22+
} = opts
23+
24+
const defaultHeaders = {
25+
'User-agent': userAgent,
2826
accept: 'application/json',
2927
}
3028

31-
this.scheme = opts.scheme
32-
this.host = opts.host
33-
this.pathPrefix = opts.pathPrefix
34-
this.globalParams = opts.globalParams
35-
this.accessToken = opts.accessToken
36-
this.agent = opts.agent
37-
38-
const methods = getMethods(this)
29+
const basePath = getBasePath({ scheme, host, pathPrefix })
30+
const methods = getMethods({ basePath, defaultHeaders, agent, globalParams })
3931
// eslint-disable-next-line fp/no-mutating-assign
40-
Object.assign(this, methods)
32+
Object.assign(this, { ...methods, defaultHeaders, scheme, host, pathPrefix, globalParams, accessToken, agent })
4133
}
4234

4335
get accessToken() {
@@ -62,12 +54,10 @@ class NetlifyAPI {
6254
}
6355

6456
get basePath() {
65-
return `${this.scheme}://${this.host}${this.pathPrefix}`
57+
return getBasePath({ scheme: this.scheme, host: this.host, pathPrefix: this.pathPrefix })
6658
}
6759

68-
async getAccessToken(ticket, opts) {
69-
opts = { poll: DEFAULT_TICKET_POLL, timeout: DEFAULT_TICKET_TIMEOUT, ...opts }
70-
60+
async getAccessToken(ticket, { poll = DEFAULT_TICKET_POLL, timeout = DEFAULT_TICKET_TIMEOUT } = {}) {
7161
const { id } = ticket
7262

7363
// ticket capture
@@ -81,8 +71,8 @@ class NetlifyAPI {
8171
}
8272

8373
await pWaitFor(checkTicket, {
84-
interval: opts.poll,
85-
timeout: opts.timeout,
74+
interval: poll,
75+
timeout,
8676
message: 'Timeout while waiting for ticket grant',
8777
})
8878

@@ -100,6 +90,10 @@ class NetlifyAPI {
10090
}
10191
}
10292

93+
const getBasePath = function ({ scheme, host, pathPrefix }) {
94+
return `${scheme}://${host}${pathPrefix}`
95+
}
96+
10397
// 1 second
10498
const DEFAULT_TICKET_POLL = 1e3
10599
// 1 hour

0 commit comments

Comments
 (0)