Skip to content
This repository was archived by the owner on Dec 9, 2024. It is now read-only.

Commit b06477c

Browse files
committed
Add support for passing stdin for invoke command.
1 parent a3fe776 commit b06477c

File tree

2 files changed

+74
-39
lines changed

2 files changed

+74
-39
lines changed

invoke/index.js

Lines changed: 44 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
const BbPromise = require('bluebird');
44
const chalk = require('chalk');
55
const path = require('path');
6+
const stdin = require('get-stdin');
7+
const fse = require('fs-extra');
68

79
const CmdLineParamsOptions = {
810
type: ['blocking', 'nonblocking'],
@@ -30,38 +32,57 @@ class OpenWhiskInvoke {
3032

3133
this.serverless.service.getFunction(this.options.function);
3234

33-
if (this.options.path) {
34-
if (!this.serverless.utils
35-
.fileExistsSync(path.join(this.serverless.config.servicePath, this.options.path))) {
36-
throw new this.serverless.classes.Error('The file path you provided does not exist.');
35+
return new Promise((resolve, reject) => {
36+
if (this.options.data) {
37+
resolve();
38+
} else if (this.options.path) {
39+
const absolutePath = path.isAbsolute(this.options.path) ?
40+
this.options.path :
41+
path.join(this.serverless.config.servicePath, this.options.path);
42+
if (!this.serverless.utils.fileExistsSync(absolutePath)) {
43+
throw new this.serverless.classes.Error('The file you provided does not exist.');
44+
}
45+
this.options.data = this.readFileSync(absolutePath);
46+
console.log(typeof this.options.data)
47+
48+
if (this.options.data == null) {
49+
throw new this.serverless.classes.Error(
50+
'The file path provided must point to a JSON file with a top-level JSON object definition.'
51+
);
52+
}
53+
resolve();
54+
} else {
55+
return this.getStdin().then(input => {
56+
this.options.data = input || '{}';
57+
resolve();
58+
});
3759
}
38-
39-
this.options.data = this.serverless.utils
40-
.readFileSync(path.join(this.serverless.config.servicePath, this.options.path));
41-
42-
if (this.options.data == null || typeof this.options.data !== 'object') {
43-
throw new this.serverless.classes.Error(
44-
'The file path provided must point to a JSON file with a top-level JSON object definition.'
45-
);
46-
}
47-
} else if (this.options.data) {
60+
}).then(() => {
4861
try {
49-
this.options.data = JSON.parse(this.options.data)
50-
} catch (e) {
62+
this.options.data = JSON.parse(this.options.data);
63+
if (this.options.data == null || typeof this.options.data !== 'object') throw new this.serverless.classes.Error('Data parameter must be a JSON object')
64+
65+
} catch (exception) {
5166
throw new this.serverless.classes.Error(
52-
'Error parsing data parameter as JSON.'
67+
`Error parsing data parameter as JSON: ${exception}`
5368
);
5469
}
55-
if (this.options.data == null || typeof this.options.data !== 'object') throw new this.serverless.classes.Error('Data parameter must be a JSON object')
56-
}
57-
58-
this.validateParamOptions();
70+
}).then(() => {
71+
this.validateParamOptions();
5972

60-
return this.provider.client().then(client => {
61-
this.client = client;
73+
return this.provider.client().then(client => {
74+
this.client = client;
75+
});
6276
});
6377
}
6478

79+
readFileSync(path) {
80+
return fse.readFileSync(path);
81+
}
82+
83+
getStdin() {
84+
return stdin()
85+
}
6586
// ensure command-line parameter values is a valid option.
6687
validateParamOptions() {
6788
Object.keys(CmdLineParamsOptions).forEach(key => {

invoke/tests/index.js

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -93,24 +93,38 @@ describe('OpenWhiskInvoke', () => {
9393
});
9494
});
9595

96-
it('it should throw if file is not parsed as JSON object', () => {
96+
it('it should parse stdin as JSON data without explicit options', () => {
97+
const data = '{"hello": "world"}';
98+
sinon.stub(openwhiskInvoke, 'getStdin').returns(BbPromise.resolve(data));
99+
100+
serverless.config.servicePath = path.join(os.tmpdir(), (new Date).getTime().toString());
101+
return openwhiskInvoke.validate().then(() => {
102+
expect(openwhiskInvoke.options.data).to.deep.equal({hello: "world"});
103+
openwhiskInvoke.options.data = null;
104+
});
105+
});
106+
107+
it('it should throw if file is not parsed as JSON object (invalid)', () => {
97108
serverless.config.servicePath = path.join(os.tmpdir(), (new Date).getTime().toString());
98-
const data = {
99-
testProp: 'testValue',
100-
};
101109
openwhiskInvoke.options.data = '{"hello": "world"';
102-
expect(() => openwhiskInvoke.validate()).to.throw(Error);
110+
return expect(openwhiskInvoke.validate()).to.eventually.be.rejectedWith('Error parsing')
111+
});
112+
113+
it('it should throw if file is not parsed as JSON object (number)', () => {
114+
serverless.config.servicePath = path.join(os.tmpdir(), (new Date).getTime().toString());
103115
openwhiskInvoke.options.data = '1';
104-
expect(() => openwhiskInvoke.validate()).to.throw(Error);
116+
return expect(openwhiskInvoke.validate()).to.eventually.be.rejectedWith('Error parsing')
105117
});
106118

107119
it('it should parse file if file path is provided', () => {
108120
serverless.config.servicePath = path.join(os.tmpdir(), (new Date).getTime().toString());
109121
const data = {
110122
testProp: 'testValue',
111123
};
112-
openwhiskInvoke.serverless.utils = {fileExistsSync: () => true, readFileSync: () => data};
124+
openwhiskInvoke.serverless.utils = {fileExistsSync: () => true};
125+
openwhiskInvoke.readFileSync = () => JSON.stringify(data);
113126
openwhiskInvoke.options.path = 'data.json';
127+
openwhiskInvoke.options.data = null;
114128

115129
return openwhiskInvoke.validate().then(() => {
116130
expect(openwhiskInvoke.options.data).to.deep.equal(data);
@@ -121,40 +135,40 @@ describe('OpenWhiskInvoke', () => {
121135

122136
it('it should throw if file is not parsed as JSON object', () => {
123137
serverless.config.servicePath = path.join(os.tmpdir(), (new Date).getTime().toString());
124-
openwhiskInvoke.serverless.utils = {fileExistsSync: () => true, readFileSync: () => 'testing'};
138+
openwhiskInvoke.serverless.utils = {fileExistsSync: () => true};
125139
openwhiskInvoke.options.path = 'data.txt';
140+
openwhiskInvoke.readFileSync = () => 'testing';
126141

127-
expect(() => openwhiskInvoke.validate()).to.throw(Error);
142+
return expect(openwhiskInvoke.validate()).to.eventually.be.rejectedWith('Error parsing')
128143
});
129144

130145
it('it should throw if type parameter is not valid value', () => {
131146
openwhiskInvoke.options.type = 'random';
132147
openwhiskInvoke.options.path = null;
133148
openwhiskInvoke.options.data = null;
134-
expect(() => openwhiskInvoke.validate()).to.throw('blocking or nonblocking');
149+
return expect(openwhiskInvoke.validate()).to.eventually.be.rejectedWith('blocking or nonblocking')
135150
});
136151

137152
it('it should throw if log parameter is not valid value', () => {
138153
openwhiskInvoke.options.type = 'blocking';
139154
openwhiskInvoke.options.log = 'random';
140155
openwhiskInvoke.options.path = null;
141-
expect(() => openwhiskInvoke.validate()).to.throw('result or response');
156+
openwhiskInvoke.options.data = '{}';
157+
return expect(openwhiskInvoke.validate()).to.eventually.be.rejectedWith('result or response')
142158
});
143159

144160
it('it should throw error if service path is not set', () => {
145161
serverless.config.servicePath = false;
146162
expect(() => openwhiskInvoke.validate()).to.throw(Error);
147-
serverless.config.servicePath = true;
148163
});
149164

150165
it('it should throw error if file path does not exist', () => {
151166
serverless.config.servicePath = path.join(os.tmpdir(), (new Date).getTime().toString());
167+
openwhiskInvoke.serverless.utils = {fileExistsSync: () => false};
152168
openwhiskInvoke.options.path = 'some/path';
169+
openwhiskInvoke.options.data = null;
153170

154-
expect(() => openwhiskInvoke.validate()).to.throw(Error);
155-
156-
openwhiskInvoke.options.path = false;
157-
serverless.config.servicePath = true;
171+
return expect(openwhiskInvoke.validate()).to.eventually.be.rejectedWith('does not exist')
158172
});
159173
});
160174

0 commit comments

Comments
 (0)