Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

makepromise

Package Overview
Dependencies
Maintainers
1
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

makepromise - npm Package Compare versions

Comparing version 1.0.0 to 1.1.0

.babelrc

1

.eslintrc.js

@@ -8,2 +8,3 @@ module.exports = {

"parserOptions": {
"ecmaVersion": 2017,
"sourceType": "module"

@@ -10,0 +11,0 @@ },

8

.vscode/launch.json

@@ -7,12 +7,16 @@ {

"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"name": "Launch Zoroaster",
"program": "${workspaceRoot}/node_modules/.bin/zoroaster",
"args": [
"test/spec/integration.js"
]
],
"env": {
"ZOROASTER_TIMEOUT": 99999999
}
}
]
}

@@ -1,22 +0,28 @@

const fs = require('fs')
const wrote = require('wrote')
const makePromise = require('../.')
const { unlink } = require('fs')
const { createWritable } = require('wrote')
const makePromise = require('../')
let file
wrote() // create a temp file and open a writable stream
.then((ws) => {
file = ws.path
return new Promise((resolve, reject) => {
ws.once('close', resolve)
ws.once('error', reject)
ws.close()
})
// here, just close the stream without makepromise, because it's a different
// kind of constructor, ie. resolve-reject and not error callback handlers
// todo: can close stream with writing null
async function closeWritable(ws) {
await new Promise((resolve, reject) => {
ws.once('close', resolve)
ws.once('error', reject)
ws.close()
})
.then(() => {
const promise = makePromise(fs.unlink, file, file)
return promise
})
.then(
(res) => { console.log(res === file) }, // true
console.error
)
}
(async () => {
// create a temp file and open a writable stream
const ws = await createWritable()
await closeWritable(ws)
const { path: file } = ws
console.log(file) // /var/folders/s0/tmp/T/wrote-69822.data
// pass 3rd argument as the return value
const resolvedFile = await makePromise(unlink, file, file)
console.log(resolvedFile === file) // true
})()

@@ -1,23 +0,26 @@

const fs = require('fs')
const wrote = require('wrote')
const makePromise = require('../.')
const { unlink } = require('fs')
const { createWritable } = require('wrote')
const makePromise = require('../')
let file
wrote() // create a temp file and open a writable stream
.then((ws) => {
file = ws.path
console.log(ws.path) // /var/folders/s0/tmp/T/wrote-69822.data
return new Promise((resolve, reject) => {
ws.once('close', resolve)
ws.once('error', reject)
ws.close()
})
// here, just close the stream without makepromise, because it's a different
// kind of constructor, ie. resolve-reject and not error callback handlers
// todo: can close stream with writing null
async function closeWritable(ws) {
await new Promise((resolve, reject) => {
ws.once('close', resolve)
ws.once('error', reject)
ws.close()
})
.then(() => {
const promise = makePromise(fs.unlink, file)
return promise
})
.then(
console.log, // undefined
console.error
)
}
(async () => {
// create a temp file and open a writable stream
const ws = await createWritable()
await closeWritable(ws)
const { path: file } = ws
console.log(file) // /var/folders/s0/tmp/T/wrote-69822.data
await makePromise(unlink, file)
})()
{
"name": "makepromise",
"version": "1.0.0",
"version": "1.1.0",
"description": "Make a native Promise from a function with a callback",
"main": "src/index",
"scripts": {
"test": "zoroaster test/spec"
"test": "zoroaster test/spec",
"test-es5": "zoroaster es5/test/spec",
"build-src": "babel src --out-dir es5/src",
"build-test": "babel test --out-dir es5/test",
"build": "run-s build-src build-test"
},

@@ -27,6 +31,15 @@ "repository": {

"devDependencies": {
"catchment": "^1.0.0",
"lockfile": "^1.0.3",
"wrote": "^0.1.0"
"babel-cli": "6.26.0",
"babel-plugin-transform-rename-import": "2.1.1",
"babel-preset-env": "1.6.1",
"catchment": "1.0.0",
"fast-async": "6.3.0",
"lockfile": "1.0.3",
"npm-run-all": "4.1.2",
"wrote": "1.0.0",
"zoroaster": "0.4.6"
},
"dependencies": {
"erotic": "0.2.0"
}
}

@@ -5,38 +5,70 @@ # makepromise

Make native Promise from function with callback
Make native `Promise` from function with callback.
## ES5
The package uses some newer language features. For your convenience, it's been
transpiled to be compatible with Node 4. You can use the following snippet.
```js
const makePromise = require('makepromise/es5/src/')
```
## `makePromise(fn:Function(...args, cb:Function(err:Error, res:any))) => Promise<any>`
Create a promise from a function which accepts callback as the last argument,
and where callback will be called with (error, result).
Create a promise from a function which accepts a callback as the last argument,
and where the callback will be called with 2 arguments: `(error, result)`.
For example, you can unlink a closed file:
For example, you can unlink a file (here, a temp file is created with
[`wrote` package][1]):
```js
'use strict'
const fs = require('fs')
const wrote = require('wrote')
const { unlink } = require('fs')
const { createWritable } = require('wrote')
const makePromise = require('makepromise')
let file
wrote() // create a temp file and open a writable stream
.then((ws) => {
file = ws.path
console.log(ws.path) // /var/folders/s0/tmp/T/wrote-69822.data
return new Promise((resolve, reject) => {
ws.once('close', resolve)
ws.once('error', reject)
ws.close()
})
(async () => {
// create a temp file and open a writable stream
const ws = await createWritable()
const { path: file } = ws // /var/folders/s0/tmp/T/wrote-69822.data
// here, just close the stream without makepromise, because it's a different
// kind of constructor, ie. resolve-reject and not error callback handlers
await new Promise((resolve, reject) => {
ws.once('close', resolve)
ws.once('error', reject)
ws.close()
})
.then(() => {
const promise = makePromise(fs.unlink, file)
return promise
})
.then(
console.log, // undefined
console.error
)
await makePromise(unlink, file)
})()
```
In addition, errors will be updated to include the stack trace of when
`makePromise` was called, rather than have node internal error stack, or no
stack at all:
```js
const fs = require('fs')
const makePromise = require('makepromise');
(async () => {
try {
await makePromise(fs.unlink, 'error-test-file')
} catch ({ stack }){
console.log(stack)
/*
Error: ENOENT: no such file or directory, unlink 'error-test-file'
at cb (makepromise/src/index.js:28:31)
at makePromise (makepromise/src/index.js:18:16)
at Object.<anonymous> (makepromise/examples/error-stack.js:4:1)
*/
// without this feature:
/*
Error: ENOENT: no such file or directory, unlink 'error-test-file'
*/
}
})()
```

@@ -49,27 +81,19 @@

```js
'use strict'
const { unlink } = require('fs')
const { createWritable } = require('wrote')
const makePromise = require('makepromise');
const fs = require('fs')
const wrote = require('wrote')
const makePromise = require('makepromise')
(async () => {
// create a temp file and open a writable stream
const ws = await createWritable()
await closeWritable(ws)
let file
wrote() // create a temp file and open a writable stream
.then((ws) => {
file = ws.path
console.log(ws.path) // /var/folders/s0/tmp/T/wrote-69822.data
return new Promise((resolve, reject) => {
ws.once('close', resolve)
ws.once('error', reject)
ws.close()
})
})
.then(() => {
const promise = makePromise(fs.unlink, file, file)
return promise
})
.then(
(res) => { console.log(res === file) }, // true
console.error
)
const { path: file } = ws
console.log(file) // /var/folders/s0/tmp/T/wrote-69822.data
// pass 3rd argument as the return value
const resolvedFile = await makePromise(unlink, file, file)
console.log(resolvedFile === file) // true
})()
```

@@ -81,8 +105,8 @@

* How to [unlock a file with](https://github.com/Sobesednik/makepromise/blob/master/test/spec/integration.js#L15)
[`lockfile`](https://www.npmjs.com/package/lockfile) and close write stream
* [How to write to a file stream](https://github.com/Sobesednik/makepromise/blob/master/test/spec/integration.js#L45) open with `fs.createWriteStream()` and end the stream
* How to [unlink a file](https://github.com/Sobesednik/makepromise/blob/master/test/spec/integration.js#L73) with `fs.unlink`
* How to [read stat](https://github.com/Sobesednik/makepromise/blob/master/test/spec/integration.js#L99) with `fs.stat`
* How to catch errors (example with trying to [call `fs.stat` with non-existent file](https://github.com/Sobesednik/makepromise/blob/master/test/spec/integration.js#L114))
* How to [unlock a file with](https://github.com/Sobesednik/makepromise/blob/master/test/spec/integration.js#L12)
[`lockfile` package][2]
* [How to write to a writable stream](https://github.com/Sobesednik/makepromise/blob/master/test/spec/integration.js#L29)
* How to [unlink a file with `fs.unlink`](https://github.com/Sobesednik/makepromise/blob/master/test/spec/integration.js#L38)
* How to [read stat with `fs.stat`](https://github.com/Sobesednik/makepromise/blob/master/test/spec/integration.js#L58)
* How to catch errors after [call `fs.stat` with non-existent file](https://github.com/Sobesednik/makepromise/blob/master/test/spec/integration.js#L66))

@@ -95,1 +119,3 @@ ---

[1]: https://www.npmjs.com/package/wrote
[2]: https://www.npmjs.com/package/lockfile

@@ -0,1 +1,9 @@

const erotic = require('erotic')
function checkArgumentIndex(length, i) {
if (i > length - 2) {
throw new Error('Function does not accept that many arguments')
}
}
/**

@@ -9,22 +17,35 @@ * Create a promise from a function.

*/
function makePromise(fn, args, resolveValue) {
async function makePromise(fn, args, resolveValue) {
const er = erotic()
if (typeof fn !== 'function') {
return Promise.reject(new Error('function must be passed'))
throw new Error('function must be passed')
}
return new Promise((resolve, reject)=> {
if (!fn.length) {
throw new Error('Function does not accept any arguments')
}
const res = await new Promise((resolve, reject)=> {
const cb = (err, res) => {
if (err) return reject(err)
if (err) {
const error = er(err)
return reject(error)
}
return resolve(resolveValue || res)
}
const allArgs = []
const allArgs = Array.from({ length: fn.length })
allArgs[allArgs.length - 1] = cb
if (Array.isArray(args)) {
args.forEach(arg => allArgs.push(arg))
} else if (args) {
allArgs.push(args)
args.forEach((arg, i) => {
checkArgumentIndex(allArgs.length, i)
allArgs[i] = arg
})
} else {
checkArgumentIndex(allArgs.length, 0)
allArgs[0] = args
}
allArgs.push(cb)
fn.apply(fn.this, allArgs)
})
return res
}
module.exports = makePromise
const assert = require('assert')
const makePromise = require('../../.')
const context = require('../context/MakePromise')
const makePromise = require('../..')
function Context() {
Object.defineProperties(this, {
testArg: {
value: 'test-arg',
},
nullErrFn: {
get: () => (arg, cb) => {
if (typeof arg === 'function') { // assume no argument is expected
return arg(null)
}
return cb(null, arg)
},
},
errFn: {
get: () => (err, cb) => cb(err, null),
},
})
}
const { equal } = assert
const makePromiseTestSuite = {
context: Context,
'should create a promise': (ctx) => {
const res = makePromise(ctx.nullErrFn)
context,
async 'should create a promise'({ nullErrFn }) {
const res =makePromise(nullErrFn)
assert(res instanceof Promise)
return res.catch(() => {})
try {
await res
} catch (err) { /* test-error */ }
},
'should resolve with undefined': (ctx) => {
const res = makePromise(ctx.nullErrFn)
return res
.then((res) => {
assert.equal(res, undefined)
})
async 'should resolve with undefined'({ nullErrFn }) {
const res = await makePromise(nullErrFn)
equal(res, undefined)
},
'should resolve with function result': (ctx) => {
const res = makePromise(ctx.nullErrFn, ctx.testArg)
return res
.then((res) => {
assert.equal(res, ctx.testArg)
})
async 'should resolve with function result'({ nullErrFn, testArg }) {
const res = await makePromise(nullErrFn, testArg)
equal(res, testArg)
},
'should reject if not a function': () => {
async 'should reject if not a function'() {
const notAFunction = 'this is not a function'
const res = makePromise(notAFunction)
return res
.then(() => {
throw new Error('should have been rejected')
}, (err) => {
assert(/function must be passed/.test(err.message))
})
try {
await makePromise(notAFunction)
throw new Error('should have been rejected')
} catch ({ message }) {
assert(/function must be passed/.test(message))
}
},
'should resolve with supplied argument': (ctx) => {
async 'should resolve with supplied argument'(ctx) {
const testValue = 'test-value'
const res = makePromise(ctx.nullErrFn, ctx.testArg, testValue)
return res
.then((res) => {
assert.equal(res, testValue)
})
const res = await makePromise(ctx.nullErrFn, ctx.testArg, testValue)
equal(res, testValue)
},
'should reject with error': (ctx) => {
async 'should reject with error'({ errFn }) {
const testError = new Error('test-error')
const res = makePromise(ctx.errFn, testError)
return res
.then(() => {
throw new Error('expected to have been rejected')
}, (err) => {
assert.equal(err, testError)
})
try {
await makePromise(errFn, testError)
throw new Error('expected to have been rejected')
} catch({ message }) {
equal(message, testError.message)
}
},
// test context
async 'should reject with error with a correct stack'(ctx) {
const testError = new Error('test-error')
delete testError.stack
try {
await makePromise(ctx.errFn, testError)
throw new Error('expected to have been rejected')
} catch ({ stack }) {
assert(stack.indexOf('should reject with error with a correct stack') != -1)
}
},
}
module.exports = makePromiseTestSuite

@@ -1,130 +0,75 @@

'use strict'
const assert = require('assert')
const wrote = require('wrote')
const fs = require('fs')
const makePromise = require('../../.')
const Stats = fs.Stats
const Catchment = require('catchment')
const lockfile = require('lockfile')
const path = require('path')
const { stat, unlink, Stats } = require('fs')
const { unlock } = require('lockfile')
const { erase, read } = require('wrote')
const context = require('../context/MakePromise')
const makePromise = require('../..')
const filepath = path.join(__dirname, '/fixtures/some-file.lock')
const { equal } = assert
const IntegrationTestSuite = {
'should be able to unlock a file': () => {
let filepath
let writeStream
return wrote()
.then((ws) => {
writeStream = ws
assert(writeStream.writable)
filepath = writeStream.path
return makePromise(fs.stat, filepath)
})
.then(() => {
return makePromise(lockfile.unlock, filepath)
})
.then(() => {
assert(writeStream.writable) // stream not closed
return makePromise(fs.stat, filepath)
})
.then(() => {
throw new Error('should have been rejected')
}, (err) => {
assert(err instanceof Error)
// console.log(Date.now(), 'no file')
assert(/ENOENT: no such file or directory, stat/.test(err.message))
return makePromise(writeStream.end.bind(writeStream))
})
.then(() => {
// console.log(Date.now(), 'write stream closed')
assert(!writeStream.writable)
})
context,
async 'should be able to unlock a file'({ getWs }) {
const ws = await getWs()
assert(ws.writable)
await makePromise(stat, ws.path)
await makePromise(unlock, ws.path)
assert(!ws.closed) // stream not closed
assert(!ws._writableState.ended)
try {
await makePromise(stat, ws.path)
throw new Error('should have been rejected')
} catch ({ code }) {
assert(code, 'ENOENT')
}
await makePromise(ws.end.bind(ws))
assert(ws.closed)
assert(ws._writableState.ended)
},
'should write to a file stream': () => {
async 'should write to a file stream'({ getWs }) {
const testData = 'some-test-data'
let catchmentPromise
let writeStream
return wrote()
.then((ws) => {
writeStream = ws
return makePromise(ws.write.bind(ws), testData, ws)
})
.then(() => {
// read file
return new Promise((resolve, reject) => {
const rs = fs.createReadStream(writeStream.path)
rs.once('open', () => resolve(rs))
rs.once('error', reject)
})
.then((rs) => {
const catchment = new Catchment()
rs.pipe(catchment)
catchmentPromise = catchment.promise
return makePromise(writeStream.end.bind(writeStream))
})
.then(() => catchmentPromise)
.then((res) => {
assert.equal(res, testData)
})
})
const ws = await getWs()
await makePromise(ws.write.bind(ws), testData)
// read file
const actual = await read(ws.path)
equal(actual, testData)
},
'should unlink a file': () => {
let file
return wrote()
.then((ws) => {
file = ws.path
return new Promise((resolve, reject) => {
ws.once('close', resolve)
ws.once('error', reject)
ws.close()
})
})
.then(() => {
const promise = makePromise(fs.unlink, file, file)
return promise
})
async 'should unlink a file'({ getWs }) {
const ws = await getWs()
await new Promise((resolve, reject) => {
ws.once('close', resolve)
ws.once('error', reject)
ws.close()
})
await makePromise(unlink, ws.path)
try {
await read(ws.path)
throw new Error('should have thrown')
} catch ({ code }) {
equal(code, 'ENOENT')
}
},
'should end stream': () => {
return wrote()
.then((ws) => {
const promise = makePromise(ws.end.bind(ws), null, ws)
return promise
})
.then((ws) => {
assert(!ws.writable)
})
async 'should end stream'({ getWs }) {
const ws = await getWs()
await makePromise(ws.end.bind(ws))
assert(ws._writableState.ended)
},
'should read stats': () => {
return wrote()
.then((ws) => {
assert(ws.writable)
const promise = makePromise(fs.stat, ws.path)
.then((res) => {
assert(res instanceof Stats)
return ws
})
return promise
})
.then((ws) => {
return wrote.erase(ws)
})
async 'should read stats'({ getWs }) {
const ws = await getWs()
assert(!ws._writableState.ended)
const res = await makePromise(stat, ws.path)
assert(res instanceof Stats)
await erase(ws) // move to context
},
'should not read stats of non-existent file': () => {
return wrote()
.then((ws) => {
return wrote.erase(ws).then(() => ws)
})
.then((ws) => {
assert(!ws.writable)
const promise = makePromise(fs.stat, ws.path)
return promise
})
.then(() => {
throw new Error('should have been rejected')
}, (err) => {
assert(err instanceof Error)
assert(/ENOENT: no such file or directory, stat/.test(err.message))
})
async 'should not read stats of non-existent file'({ getWs }) {
const ws = await getWs()
await erase(ws)
try {
await makePromise(stat, ws.path)
throw new Error('should have been rejected')
} catch ({ code }) {
equal(code, 'ENOENT')
}
},

@@ -131,0 +76,0 @@ }

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc