Skip to content

Commit 0f30547

Browse files
authored
feat: add types (#651)
Adds typescript support for this module. BREAKING CHANGE: things are now typed which may be suprising
1 parent 1b4b936 commit 0f30547

22 files changed

+429
-207
lines changed

.github/workflows/main.yml

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ jobs:
1919
- run: npm run lint
2020
- run: npm run build
2121
- run: npx aegir dep-check
22+
- uses: gozala/typescript-error-reporter-action@v1.0.8
2223
#- uses: ipfs/aegir/actions/bundle-size@master
2324
# name: size
2425
# with:

package.json

+10-11
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"jsdelivr": "dist/index.min.js",
99
"unpkg": "dist/index.min.js",
1010
"scripts": {
11-
"lint": "aegir lint",
11+
"lint": "aegir ts -p check && aegir lint",
1212
"docs": "aegir docs",
1313
"build": "aegir build",
1414
"test": "aegir test",
@@ -42,8 +42,7 @@
4242
"@hapi/hapi": "^20.0.0",
4343
"debug": "^4.1.1",
4444
"execa": "^5.0.0",
45-
"fs-extra": "^9.0.0",
46-
"ipfs-utils": "^7.0.0",
45+
"ipfs-utils": "^8.1.4",
4746
"joi": "^17.2.1",
4847
"merge-options": "^3.0.1",
4948
"multiaddr": "^10.0.0",
@@ -52,14 +51,14 @@
5251
"temp-write": "^4.0.0"
5352
},
5453
"devDependencies": {
55-
"aegir": "^33.0.0",
56-
"assert": "^2.0.0",
57-
"benchmark": "^2.1.4",
58-
"go-ipfs": "^0.8.0",
59-
"ipfs": "next",
60-
"ipfs-client": "next",
61-
"ipfs-http-client": "next",
62-
"ipfs-unixfs": "^4.0.1"
54+
"@types/hapi__hapi": "^20.0.9",
55+
"aegir": "^34.1.0",
56+
"go-ipfs": "^0.9.1",
57+
"ipfs": "^0.56.1",
58+
"ipfs-client": "^0.5.1",
59+
"ipfs-http-client": "^51.0.1",
60+
"ipfs-unixfs": "^5.0.0",
61+
"util": "^0.12.4"
6362
},
6463
"repository": {
6564
"type": "git",

src/config.js

+5
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@
22

33
const { isBrowser, isWebWorker } = require('ipfs-utils/src/env')
44

5+
/**
6+
* @param {object} args
7+
* @param {import('./types').NodeType} args.type
8+
*/
59
module.exports = ({ type }) => {
10+
/** @type {string[]} */
611
let swarm
712

813
// from the browser tell remote nodes to listen over WS

src/endpoint/routes.js

+8-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ const routeOptions = {
1313
})
1414
}
1515
}
16+
17+
/**
18+
* @param {Error & { stdout?: string }} err
19+
*/
1620
const badRequest = err => {
1721
let msg
1822
if (err.stdout) {
@@ -24,12 +28,15 @@ const badRequest = err => {
2428
throw boom.badRequest(msg)
2529
}
2630

31+
/**
32+
* @type {Record<string, any>}
33+
*/
2734
const nodes = {}
2835

2936
/**
3037
* @namespace EndpointServerRoutes
3138
* @ignore
32-
* @param {Hapi.Server} server
39+
* @param {import('@hapi/hapi').Server} server
3340
* @param {Function} createFactory
3441
* @returns {void}
3542
*/

src/endpoint/server.browser.js

+6-6
Original file line numberDiff line numberDiff line change
@@ -25,21 +25,21 @@ class Server {
2525
/**
2626
* Start the server
2727
*
28-
* @returns {Promise<Hapi.Server>}
28+
* @returns {Promise<Server>}
2929
*/
30-
start () {
30+
async start () {
3131
console.warn('Server not implemented in the browser')
32-
return Promise.resolve(this)
32+
33+
return this
3334
}
3435

3536
/**
3637
* Stop the server
3738
*
38-
* @returns {Promise}
39+
* @returns {Promise<void>}
3940
*/
40-
stop () {
41+
async stop () {
4142
console.warn('Server not implemented in the browser')
42-
return Promise.resolve(this)
4343
}
4444
}
4545

src/endpoint/server.js

+14-9
Original file line numberDiff line numberDiff line change
@@ -12,22 +12,23 @@ class Server {
1212
/**
1313
* @class
1414
* @param {Object} options
15-
* @param {number} [options.port=43134] - Server port.
15+
* @param {number} [options.port=43134]
16+
* @param {string} [options.host='localhost']
1617
* @param {Function} createFactory
1718
*/
1819
constructor (options = { port: 43134, host: 'localhost' }, createFactory) {
1920
this.options = options
2021
this.server = null
21-
this.port = this.options.port
22-
this.host = this.options.host
22+
this.port = this.options.port == null ? 43134 : this.options.port
23+
this.host = this.options.host == null ? 'localhost' : this.options.host
2324
this.createFactory = createFactory
2425
}
2526

2627
/**
2728
* Start the server
2829
*
2930
* @param {number} port
30-
* @returns {Promise<Hapi.Server>}
31+
* @returns {Promise<Server>}
3132
*/
3233
async start (port = this.port) {
3334
this.port = port
@@ -42,17 +43,21 @@ class Server {
4243
routes(this.server, this.createFactory)
4344

4445
await this.server.start()
45-
return this.server
46+
47+
return this
4648
}
4749

4850
/**
4951
* Stop the server
5052
*
51-
* @param {object} [options] - {@link https://hapi.dev/api/?v=18.4.0#-await-serverstopoptions Hapi docs}
52-
* @returns {Promise}
53+
* @param {object} [options]
54+
* @param {number} options.timeout
55+
* @returns {Promise<void>}
5356
*/
54-
stop (options) {
55-
return this.server.stop(options)
57+
async stop (options) {
58+
if (this.server) {
59+
await this.server.stop(options)
60+
}
5661
}
5762
}
5863

src/factory.js

+20-17
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,12 @@ const ControllerRemote = require('./ipfsd-client')
88
const ControllerProc = require('./ipfsd-in-proc')
99
const testsConfig = require('./config')
1010

11-
/** @typedef {import("./index").ControllerOptions} ControllerOptions */
12-
/** @typedef {import("./index").ControllerOptionsOverrides} ControllerOptionsOverrides */
13-
/** @typedef {import("./index").IpfsOptions} IpfsOptions */
11+
/**
12+
* @typedef {import("./types").ControllerOptions} ControllerOptions
13+
* @typedef {import("./types").ControllerOptionsOverrides} ControllerOptionsOverrides
14+
* @typedef {import("./types").IPFSOptions} IPFSOptions
15+
* @typedef {import('./types').Controller} Controller
16+
*/
1417

1518
const defaults = {
1619
remote: !isNode,
@@ -45,7 +48,7 @@ class Factory {
4548
proc: merge(this.opts, { type: 'proc' })
4649
}, overrides)
4750

48-
/** @type ControllerDaemon[] */
51+
/** @type {Controller[]} */
4952
this.controllers = []
5053
}
5154

@@ -54,25 +57,28 @@ class Factory {
5457
* useful in browsers to be able to generate temp
5558
* repos manually
5659
*
57-
* @param {ControllerOptions} options - Controller type
58-
*
60+
* @param {ControllerOptions} [options]
5961
* @returns {Promise<string>}
6062
*/
61-
async tmpDir (options) {
62-
options = merge(this.opts, options)
63-
if (options.remote) {
63+
async tmpDir (options = {}) {
64+
const opts = merge(this.opts, options)
65+
66+
if (opts.remote) {
6467
const res = await http.get(
65-
`${options.endpoint}/util/tmp-dir`,
66-
{ searchParams: { type: options.type } }
68+
`${opts.endpoint}/util/tmp-dir`,
69+
{ searchParams: new URLSearchParams({ type: `${opts.type}` }) }
6770
)
6871
const out = await res.json()
6972

7073
return out.tmpDir
7174
}
7275

73-
return Promise.resolve(tmpDir(options.type))
76+
return Promise.resolve(tmpDir(opts.type))
7477
}
7578

79+
/**
80+
* @param {IPFSOptions & { endpoint: string }} options
81+
*/
7682
async _spawnRemote (options) {
7783
const opts = {
7884
json: {
@@ -100,10 +106,10 @@ class Factory {
100106
* Spawn an IPFSd Controller
101107
*
102108
* @param {ControllerOptions} options
103-
* @returns {Promise<ControllerDaemon>}
109+
* @returns {Promise<ControllerDaemon | ControllerProc | ControllerRemote>}
104110
*/
105111
async spawn (options = { }) {
106-
const type = options.type || this.opts.type
112+
const type = options.type || this.opts.type || 'go'
107113
const opts = merge(
108114
this.overrides[type],
109115
options
@@ -152,13 +158,10 @@ class Factory {
152158

153159
/**
154160
* Stop all controllers
155-
*
156-
* @returns {Promise<ControllerDaemon[]>}
157161
*/
158162
async clean () {
159163
await Promise.all(this.controllers.map(n => n.stop()))
160164
this.controllers = []
161-
return this
162165
}
163166
}
164167

src/index.js

+10-54
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,17 @@
33
const Factory = require('./factory')
44
const Server = require('./endpoint/server')
55

6-
/** @typedef {import("./ipfsd-daemon")} Controller */
6+
/**
7+
* @typedef {import("./types").Controller} Controller
8+
* @typedef {import("./types").ControllerOptions} ControllerOptions
9+
* @typedef {import("./types").ControllerOptionsOverrides} ControllerOptionsOverrides
10+
*/
711

812
/**
913
* Creates a factory
1014
*
11-
* @param {ControllerOptions} options
12-
* @param {ControllerOptionsOverrides} overrides
15+
* @param {ControllerOptions} [options]
16+
* @param {ControllerOptionsOverrides} [overrides]
1317
* @returns {Factory}
1418
*/
1519
const createFactory = (options, overrides) => {
@@ -30,11 +34,9 @@ const createController = (options) => {
3034
/**
3135
* Create a Endpoint Server
3236
*
33-
* @param {(Object|number)} options - Configuration options or just the port.
34-
* @param {number} options.port - Port to start the server on.
35-
* @param {ControllerOptions} factoryOptions
36-
* @param {ControllerOptionsOverrides} factoryOverrides
37-
* @returns {Server}
37+
* @param {number | { port: number }} [options] - Configuration options or just the port.
38+
* @param {ControllerOptions} [factoryOptions]
39+
* @param {ControllerOptionsOverrides} [factoryOverrides]
3840
*/
3941
const createServer = (options, factoryOptions = {}, factoryOverrides = {}) => {
4042
if (typeof options === 'number') {
@@ -51,49 +53,3 @@ module.exports = {
5153
createController,
5254
createServer
5355
}
54-
55-
/**
56-
* Same as https://github.com/ipfs/js-ipfs/blob/master/README.md#ipfs-constructor
57-
*
58-
* @typedef {Object} IpfsOptions
59-
* @property {string|Object} [repo] - The file path at which to store the IPFS node’s data. Alternatively, you can set up a customized storage system by providing an ipfs.Repo instance.
60-
* @property {boolean|Object} [init=true] - Initialize the repo when creating the IPFS node. Instead of a boolean, you may provide an object with custom initialization options. https://github.com/ipfs/js-ipfs/blob/master/README.md#optionsinit
61-
* @property {boolean} [start=true] - If false, do not automatically start the IPFS node. Instead, you’ll need to manually call node.start() yourself.
62-
* @property {string} [pass=null] - A passphrase to encrypt/decrypt your keys.
63-
* @property {boolean} [silent=false] - Prevents all logging output from the IPFS node.
64-
* @property {object} [relay] - Configure circuit relay. https://github.com/ipfs/js-ipfs/blob/master/README.md#optionsrelay Default: `{ enabled: true, hop: { enabled: false, active: false } }`
65-
* @property {object} [preload] - Configure remote preload nodes. The remote will preload content added on this node, and also attempt to preload objects requested by this node. https://github.com/ipfs/js-ipfs/blob/master/README.md#optionspreload Default: `{ enabled: true, addresses: [...]`
66-
* @property {object} [EXPERIMENTAL] - Enable and configure experimental features. https://github.com/ipfs/js-ipfs/blob/master/README.md#optionsexperimental Default: `{ ipnsPubsub: false, sharding: false }`
67-
* @property {object} [config] - Modify the default IPFS node config. This object will be merged with the default config; it will not replace it. The default config is documented in the js-ipfs config file docs. https://github.com/ipfs/js-ipfs/blob/master/README.md#optionsconfig
68-
* @property {object} [ipld] - Modify the default IPLD config. This object will be merged with the default config; it will not replace it. Check IPLD docs for more information on the available options. https://github.com/ipfs/js-ipfs/blob/master/README.md#optionsipld
69-
* @property {object | Function} [libp2p] - The libp2p option allows you to build your libp2p node by configuration, or via a bundle function. https://github.com/ipfs/js-ipfs/blob/master/README.md#optionslibp2p
70-
* @property {object} [connectionManager] - Configure the libp2p connection manager. https://github.com/ipfs/js-ipfs/blob/master/README.md#optionsconnectionmanager
71-
* @property {boolean} [offline=false] - Run the node offline.
72-
*/
73-
74-
/**
75-
* @typedef {Object} ControllerOptions
76-
* @property {boolean} [test=false] - Flag to activate custom config for tests.
77-
* @property {boolean} [remote] - Use remote endpoint to spawn the controllers. Defaults to `true` when not in node.
78-
* @property {string} [endpoint] - Endpoint URL to manage remote Controllers. (Defaults: 'http://localhost:43134').
79-
* @property {boolean} [disposable=true] - A new repo is created and initialized for each invocation, as well as cleaned up automatically once the process exits.
80-
* @property {string} [type] - The daemon type, see below the options:
81-
* - go - spawn go-ipfs daemon node
82-
* - js - spawn js-ipfs daemon node
83-
* - proc - spawn in-process js-ipfs node
84-
* @property {Object} [env] - Additional environment variables, passed to executing shell. Only applies for Daemon controllers.
85-
* @property {Array} [args] - Custom cli args.
86-
* @property {Object} [ipfsHttpModule] - Reference to a IPFS HTTP Client object.
87-
* @property {Object} [ipfsModule] - Reference to a IPFS API object.
88-
* @property {string} [ipfsBin] - Path to a IPFS exectutable.
89-
* @property {IpfsOptions} [ipfsOptions] - Options for the IPFS node.
90-
* @property {boolean} [forceKill] - Whether to use SIGKILL to quit a daemon that does not stop after `.stop()` is called. (default true)
91-
* @property {number} [forceKillTimeout] - How long to wait before force killing a daemon in ms. (default 5000)
92-
*/
93-
94-
/**
95-
* @typedef {Object} ControllerOptionsOverrides
96-
* @property {ControllerOptions} [js] - Pre-defined defaults options for **JS** controllers these are deep merged with options passed to `Factory.spawn(options)`.
97-
* @property {ControllerOptions} [go] - Pre-defined defaults options for **Go** controllers these are deep merged with options passed to `Factory.spawn(options)`.
98-
* @property {ControllerOptions} [proc] - Pre-defined defaults options for **Proc** controllers these are deep merged with options passed to `Factory.spawn(options)`.
99-
*/

0 commit comments

Comments
 (0)