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

Commit aa0ab56

Browse files
committed
Simplify options handling
1 parent 86d434a commit aa0ab56

File tree

8 files changed

+84
-96
lines changed

8 files changed

+84
-96
lines changed

.eslintrc.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ module.exports = {
99
'max-statements': 0,
1010
'no-await-in-loop': 0,
1111
'no-magic-numbers': 0,
12-
'no-param-reassign': 0,
1312
'fp/no-class': 0,
1413
'fp/no-let': 0,
1514
'fp/no-loops': 0,

src/deploy/hash_files.js

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,25 @@ const pump = promisify(require('pump'))
55

66
const { hasherCtor, manifestCollectorCtor, fileFilterCtor, fileNormalizerCtor } = require('./hasher_segments')
77

8-
const hashFiles = async (dir, configPath, opts) => {
9-
opts = {
10-
concurrentHash: 100,
11-
assetType: 'file',
12-
statusCb: () => {},
13-
...opts,
14-
}
15-
16-
if (!opts.filter) throw new Error('Missing filter function option')
17-
const fileStream = walker([configPath, dir], { filter: opts.filter })
18-
const filter = fileFilterCtor()
19-
const hasher = hasherCtor(opts)
20-
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 })
2118

2219
// Written to by manifestCollector
2320
// normalizedPath: hash (wanted by deploy API)
2421
const files = {}
2522
// hash: [fileObj, fileObj, fileObj]
2623
const filesShaMap = {}
27-
const manifestCollector = manifestCollectorCtor(files, filesShaMap, opts)
24+
const manifestCollector = manifestCollectorCtor(files, filesShaMap, { statusCb, assetType })
2825

29-
await pump(fileStream, filter, hasher, fileNormalizer, manifestCollector)
26+
await pump(fileStream, fileFilter, hasher, fileNormalizer, manifestCollector)
3027

3128
return { files, filesShaMap }
3229
}

src/deploy/hash_files.test.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ const { defaultFilter } = require('./util')
88
test('hashes files in a folder', async (t) => {
99
const { files, filesShaMap } = await hashFiles(__dirname, path.resolve(__dirname, '../../fixtures/netlify.toml'), {
1010
filter: defaultFilter,
11+
statusCb() {},
12+
concurrentHash: 100,
1113
})
1214
t.truthy(files['netlify.toml'], 'includes the netlify.toml file')
1315
Object.keys(files).forEach((filePath) => {

src/deploy/hash_fns.js

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,17 @@ const pump = promisify(require('pump'))
77

88
const { hasherCtor, manifestCollectorCtor } = require('./hasher_segments')
99

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

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

2517
const fileObjs = functionZips.map(({ path: functionPath, runtime }) => ({
2618
filepath: functionPath,
27-
root: opts.tmpDir,
28-
relname: path.relative(opts.tmpDir, functionPath),
19+
root: tmpDir,
20+
relname: path.relative(tmpDir, functionPath),
2921
basename: path.basename(functionPath),
3022
extname: path.extname(functionPath),
3123
type: 'file',
@@ -36,14 +28,14 @@ const hashFns = async (dir, opts) => {
3628

3729
const functionStream = fromArray.obj(fileObjs)
3830

39-
const hasher = hasherCtor(opts)
31+
const hasher = hasherCtor({ concurrentHash, hashAlgorithm })
4032

4133
// Written to by manifestCollector
4234
// normalizedPath: hash (wanted by deploy API)
4335
const functions = {}
4436
// hash: [fileObj, fileObj, fileObj]
4537
const fnShaMap = {}
46-
const manifestCollector = manifestCollectorCtor(functions, fnShaMap, opts)
38+
const manifestCollector = manifestCollectorCtor(functions, fnShaMap, { statusCb, assetType })
4739

4840
await pump(functionStream, hasher, manifestCollector)
4941

src/deploy/hash_fns.test.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@ const test = require('ava')
22
const tempy = require('tempy')
33

44
const hashFns = require('./hash_fns')
5-
const { defaultFilter } = require('./util')
65

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

1013
Object.keys(functions).forEach((path) => {
1114
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
@@ -10,26 +10,29 @@ const uploadFiles = require('./upload_files')
1010
const { waitForDiff } = require('./util')
1111
const { waitForDeploy, getUploadList, defaultFilter } = require('./util')
1212

13-
const deploySite = async (api, siteId, dir, opts) => {
14-
opts = {
15-
fnDir: null,
16-
configPath: null,
17-
draft: false,
13+
const deploySite = async (
14+
api,
15+
siteId,
16+
dir,
17+
{
18+
fnDir = null,
19+
configPath = null,
20+
draft = false,
1821
// API calls this the 'title'
19-
message: undefined,
20-
tmpDir: tempy.directory(),
22+
message: title,
23+
tmpDir = tempy.directory(),
2124
// local deploy timeout: 20 mins
22-
deployTimeout: 1.2e6,
25+
deployTimeout = 1.2e6,
2326
// concurrent file hash calls
24-
concurrentHash: 100,
27+
concurrentHash = 100,
2528
// Number of concurrent uploads
26-
concurrentUpload: 5,
27-
filter: defaultFilter,
29+
concurrentUpload = 5,
30+
filter = defaultFilter,
2831
// number of files
29-
syncFileLimit: 100,
32+
syncFileLimit = 100,
3033
// number of times to retry an upload
31-
maxRetry: 5,
32-
statusCb: () => {
34+
maxRetry = 5,
35+
statusCb = () => {
3336
/* default to noop */
3437
// statusObj: {
3538
// type: name-of-step
@@ -38,22 +41,21 @@ const deploySite = async (api, siteId, dir, opts) => {
3841
// spinner: a spinner from cli-spinners package
3942
// }
4043
},
41-
// allows updating an existing deploy
42-
deployId: null,
43-
...opts,
44-
}
45-
46-
const { fnDir, configPath, statusCb, message: title } = opts
47-
44+
deployId: deployIdOpt = null,
45+
hashAlgorithm,
46+
assetType,
47+
branch,
48+
} = {},
49+
) => {
4850
statusCb({
4951
type: 'hashing',
5052
msg: `Hashing files...`,
5153
phase: 'start',
5254
})
5355

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

5961
const filesCount = Object.keys(files).length
@@ -81,22 +83,22 @@ const deploySite = async (api, siteId, dir, opts) => {
8183
body: {
8284
files,
8385
functions,
84-
async: Object.keys(files).length > opts.syncFileLimit,
85-
branch: opts.branch,
86-
draft: opts.draft,
86+
async: Object.keys(files).length > syncFileLimit,
87+
branch,
88+
draft,
8789
},
8890
})
89-
if (opts.deployId === null) {
91+
if (deployIdOpt === null) {
9092
if (title) {
9193
deployParams = { ...deployParams, title }
9294
}
9395
deploy = await api.createSiteDeploy(deployParams)
9496
} else {
95-
deployParams = { ...deployParams, deploy_id: opts.deployId }
97+
deployParams = { ...deployParams, deploy_id: deployIdOpt }
9698
deploy = await api.updateSiteDeploy(deployParams)
9799
}
98100

99-
if (deployParams.body.async) deploy = await waitForDiff(api, deploy.id, siteId, opts.deployTimeout)
101+
if (deployParams.body.async) deploy = await waitForDiff(api, deploy.id, siteId, deployTimeout)
100102

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

@@ -110,22 +112,22 @@ const deploySite = async (api, siteId, dir, opts) => {
110112

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

113-
await uploadFiles(api, deployId, uploadList, opts)
115+
await uploadFiles(api, deployId, uploadList, { concurrentUpload, statusCb, maxRetry })
114116

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

122124
statusCb({
123125
type: 'wait-for-deploy',
124-
msg: opts.draft ? 'Draft deploy is live!' : 'Deploy is live!',
126+
msg: draft ? 'Draft deploy is live!' : 'Deploy is live!',
125127
phase: 'stop',
126128
})
127129

128-
await rimraf(opts.tmpDir)
130+
await rimraf(tmpDir)
129131

130132
const deployManifest = {
131133
deployId,

src/index.js

Lines changed: 19 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6,36 +6,29 @@ const { addMethods } = require('./methods')
66
const { getOperations } = require('./operations')
77

88
class NetlifyAPI {
9-
constructor(accessToken, opts) {
9+
constructor(firstArg, secondArg) {
1010
addMethods(this)
1111

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

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

33-
this.scheme = opts.scheme
34-
this.host = opts.host
35-
this.pathPrefix = opts.pathPrefix
36-
this.globalParams = opts.globalParams
37-
this.accessToken = opts.accessToken
38-
this.agent = opts.agent
31+
Object.assign(this, { defaultHeaders, scheme, host, pathPrefix, globalParams, accessToken, agent })
3932
}
4033

4134
get accessToken() {
@@ -63,9 +56,7 @@ class NetlifyAPI {
6356
return `${this.scheme}://${this.host}${this.pathPrefix}`
6457
}
6558

66-
async getAccessToken(ticket, opts) {
67-
opts = { poll: 1000, timeout: 3.6e6, ...opts }
68-
59+
async getAccessToken(ticket, { poll = 1000, timeout = 3.6e6 } = {}) {
6960
const { id } = ticket
7061

7162
// ticket capture
@@ -79,8 +70,8 @@ class NetlifyAPI {
7970
}
8071

8172
await pWaitFor(checkTicket, {
82-
interval: opts.poll,
83-
timeout: opts.timeout,
73+
interval: poll,
74+
timeout,
8475
message: 'Timeout while waiting for ticket grant',
8576
})
8677

0 commit comments

Comments
 (0)