mirror of
https://github.com/fjogeleit/http-request-action.git
synced 2024-11-25 05:10:57 -05:00
Merge pull request #37 from Atlas-Authority/master
Support single file upload
This commit is contained in:
commit
d45f6649f6
8 changed files with 86 additions and 12 deletions
7
.github/workflows/test.yml
vendored
7
.github/workflows/test.yml
vendored
|
@ -61,3 +61,10 @@ jobs:
|
|||
method: 'POST'
|
||||
data: '{ "key": "value" }'
|
||||
files: '{ "file": "${{ github.workspace }}/testfile.txt" }'
|
||||
|
||||
- name: Request Postman Echo POST single file
|
||||
uses: ./
|
||||
with:
|
||||
url: 'https://postman-echo.com/post'
|
||||
method: 'POST'
|
||||
file: "${{ github.workspace }}/testfile.txt"
|
||||
|
|
|
@ -26,6 +26,7 @@ jobs:
|
|||
|contentType | Request ContentType| application/json |
|
||||
|data | Request Body Content:<br>- text content like JSON or XML<br>- key=value pairs separated by '&' and contentType: application/x-www-form-urlencoded<br><br>only for POST / PUT / PATCH Requests | '{}' |
|
||||
|files | Map of key / absolute file paths send as multipart/form-data request to the API, if set the contentType is set to multipart/form-data, values provided by data will be added as additional FormData values, nested objects are not supported. **Example provided in the _test_ Workflow of this Action** | '{}' |
|
||||
|file | Single absolute file path send as `application/octet-stream` request to the API, if set the contentType is set to `application/octet-stream`. This input will be ignored if either `data` or `files` input is present. **Example provided in the _test_ Workflow of this Action** ||
|
||||
|timeout| Request Timeout in ms | 5000 (5s) |
|
||||
|username| Username for Basic Auth ||
|
||||
|password| Password for Basic Auth ||
|
||||
|
|
|
@ -19,6 +19,9 @@ inputs:
|
|||
description: 'Map of absolute file paths as JSON String'
|
||||
required: false
|
||||
default: '{}'
|
||||
file:
|
||||
description: 'A single absolute file path'
|
||||
required: false
|
||||
username:
|
||||
description: 'Auth Username'
|
||||
required: false
|
||||
|
|
40
dist/index.js
vendored
40
dist/index.js
vendored
|
@ -1909,6 +1909,7 @@ const METHOD_POST = 'POST'
|
|||
* @param {{ baseURL: string; timeout: number; headers: { [name: string]: string } }} param0.instanceConfig
|
||||
* @param {string} param0.data Request Body as string, default {}
|
||||
* @param {string} param0.files Map of Request Files (name: absolute path) as JSON String, default: {}
|
||||
* @param {string} param0.file Single request file (absolute path)
|
||||
* @param {{ username: string; password: string }|undefined} param0.auth Optional HTTP Basic Auth
|
||||
* @param {*} param0.actions
|
||||
* @param {number[]} param0.ignoredCodes Prevent Action to fail if the API response with one of this StatusCodes
|
||||
|
@ -1917,7 +1918,7 @@ const METHOD_POST = 'POST'
|
|||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
const request = async({ method, instanceConfig, data, files, auth, actions, ignoredCodes, preventFailureOnNoResponse, escapeData }) => {
|
||||
const request = async({ method, instanceConfig, data, files, file, auth, actions, ignoredCodes, preventFailureOnNoResponse, escapeData }) => {
|
||||
try {
|
||||
if (escapeData) {
|
||||
data = data.replace(/"[^"]*"/g, (match) => {
|
||||
|
@ -1930,8 +1931,8 @@ const request = async({ method, instanceConfig, data, files, auth, actions, igno
|
|||
}
|
||||
|
||||
if (files && files !== '{}') {
|
||||
filesJson = convertToJSON(files)
|
||||
dataJson = convertToJSON(data)
|
||||
let filesJson = convertToJSON(files)
|
||||
let dataJson = convertToJSON(data)
|
||||
|
||||
if (Object.keys(filesJson).length > 0) {
|
||||
try {
|
||||
|
@ -1944,6 +1945,12 @@ const request = async({ method, instanceConfig, data, files, auth, actions, igno
|
|||
}
|
||||
}
|
||||
|
||||
// Only consider file if neither data nor files provided
|
||||
if ((!data || data === '{}') && (!files || files === '{}') && file) {
|
||||
data = fs.createReadStream(file)
|
||||
updateConfigForFile(instanceConfig, file, actions)
|
||||
}
|
||||
|
||||
const requestData = {
|
||||
auth,
|
||||
method,
|
||||
|
@ -2041,6 +2048,30 @@ const updateConfig = async (instanceConfig, formData, actions) => {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param instanceConfig
|
||||
* @param filePath
|
||||
* @param {*} actions
|
||||
*
|
||||
* @returns {{ baseURL: string; timeout: number; headers: { [name: string]: string } }}
|
||||
*/
|
||||
const updateConfigForFile = (instanceConfig, filePath, actions) => {
|
||||
try {
|
||||
const { size } = fs.statSync(filePath)
|
||||
|
||||
return {
|
||||
...instanceConfig,
|
||||
headers: {
|
||||
...instanceConfig.headers,
|
||||
'Content-Length': size,
|
||||
'Content-Type': 'application/octet-stream'
|
||||
}
|
||||
}
|
||||
} catch(error) {
|
||||
actions.setFailed({ message: `Unable to read Content-Length: ${error.message}`, data, files })
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {FormData} formData
|
||||
*
|
||||
|
@ -4898,6 +4929,7 @@ const instanceConfig = {
|
|||
|
||||
const data = core.getInput('data') || '{}';
|
||||
const files = core.getInput('files') || '{}';
|
||||
const file = core.getInput('file')
|
||||
const method = core.getInput('method') || METHOD_POST;
|
||||
const preventFailureOnNoResponse = core.getInput('preventFailureOnNoResponse') === 'true';
|
||||
const escapeData = core.getInput('escapeData') === 'true';
|
||||
|
@ -4909,7 +4941,7 @@ if (typeof ignoreStatusCodes === 'string' && ignoreStatusCodes.length > 0) {
|
|||
ignoredCodes = ignoreStatusCodes.split(',').map(statusCode => parseInt(statusCode.trim()))
|
||||
}
|
||||
|
||||
request({ data, method, instanceConfig, auth, preventFailureOnNoResponse, escapeData, files, ignoredCodes, actions: new GithubActions() })
|
||||
request({ data, method, instanceConfig, auth, preventFailureOnNoResponse, escapeData, files, file, ignoredCodes, actions: new GithubActions() })
|
||||
|
||||
|
||||
/***/ }),
|
||||
|
|
5
package-lock.json
generated
5
package-lock.json
generated
|
@ -1,12 +1,11 @@
|
|||
{
|
||||
"name": "http-request-action",
|
||||
"version": "1.8.0",
|
||||
"version": "1.9.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "http-request-action",
|
||||
"version": "1.8.0",
|
||||
"version": "1.9.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@zeit/ncc": "^0.22",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "http-request-action",
|
||||
"version": "1.8.2",
|
||||
"version": "1.9.0",
|
||||
"description": "",
|
||||
"main": "src/index.js",
|
||||
"private": false,
|
||||
|
|
|
@ -11,6 +11,7 @@ const METHOD_POST = 'POST'
|
|||
* @param {{ baseURL: string; timeout: number; headers: { [name: string]: string } }} param0.instanceConfig
|
||||
* @param {string} param0.data Request Body as string, default {}
|
||||
* @param {string} param0.files Map of Request Files (name: absolute path) as JSON String, default: {}
|
||||
* @param {string} param0.file Single request file (absolute path)
|
||||
* @param {{ username: string; password: string }|undefined} param0.auth Optional HTTP Basic Auth
|
||||
* @param {*} param0.actions
|
||||
* @param {number[]} param0.ignoredCodes Prevent Action to fail if the API response with one of this StatusCodes
|
||||
|
@ -19,7 +20,7 @@ const METHOD_POST = 'POST'
|
|||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
const request = async({ method, instanceConfig, data, files, auth, actions, ignoredCodes, preventFailureOnNoResponse, escapeData }) => {
|
||||
const request = async({ method, instanceConfig, data, files, file, auth, actions, ignoredCodes, preventFailureOnNoResponse, escapeData }) => {
|
||||
try {
|
||||
if (escapeData) {
|
||||
data = data.replace(/"[^"]*"/g, (match) => {
|
||||
|
@ -32,8 +33,8 @@ const request = async({ method, instanceConfig, data, files, auth, actions, igno
|
|||
}
|
||||
|
||||
if (files && files !== '{}') {
|
||||
filesJson = convertToJSON(files)
|
||||
dataJson = convertToJSON(data)
|
||||
let filesJson = convertToJSON(files)
|
||||
let dataJson = convertToJSON(data)
|
||||
|
||||
if (Object.keys(filesJson).length > 0) {
|
||||
try {
|
||||
|
@ -46,6 +47,12 @@ const request = async({ method, instanceConfig, data, files, auth, actions, igno
|
|||
}
|
||||
}
|
||||
|
||||
// Only consider file if neither data nor files provided
|
||||
if ((!data || data === '{}') && (!files || files === '{}') && file) {
|
||||
data = fs.createReadStream(file)
|
||||
updateConfigForFile(instanceConfig, file, actions)
|
||||
}
|
||||
|
||||
const requestData = {
|
||||
auth,
|
||||
method,
|
||||
|
@ -143,6 +150,30 @@ const updateConfig = async (instanceConfig, formData, actions) => {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param instanceConfig
|
||||
* @param filePath
|
||||
* @param {*} actions
|
||||
*
|
||||
* @returns {{ baseURL: string; timeout: number; headers: { [name: string]: string } }}
|
||||
*/
|
||||
const updateConfigForFile = (instanceConfig, filePath, actions) => {
|
||||
try {
|
||||
const { size } = fs.statSync(filePath)
|
||||
|
||||
return {
|
||||
...instanceConfig,
|
||||
headers: {
|
||||
...instanceConfig.headers,
|
||||
'Content-Length': size,
|
||||
'Content-Type': 'application/octet-stream'
|
||||
}
|
||||
}
|
||||
} catch(error) {
|
||||
actions.setFailed({ message: `Unable to read Content-Length: ${error.message}`, data, files })
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {FormData} formData
|
||||
*
|
||||
|
|
|
@ -36,6 +36,7 @@ const instanceConfig = {
|
|||
|
||||
const data = core.getInput('data') || '{}';
|
||||
const files = core.getInput('files') || '{}';
|
||||
const file = core.getInput('file')
|
||||
const method = core.getInput('method') || METHOD_POST;
|
||||
const preventFailureOnNoResponse = core.getInput('preventFailureOnNoResponse') === 'true';
|
||||
const escapeData = core.getInput('escapeData') === 'true';
|
||||
|
@ -47,4 +48,4 @@ if (typeof ignoreStatusCodes === 'string' && ignoreStatusCodes.length > 0) {
|
|||
ignoredCodes = ignoreStatusCodes.split(',').map(statusCode => parseInt(statusCode.trim()))
|
||||
}
|
||||
|
||||
request({ data, method, instanceConfig, auth, preventFailureOnNoResponse, escapeData, files, ignoredCodes, actions: new GithubActions() })
|
||||
request({ data, method, instanceConfig, auth, preventFailureOnNoResponse, escapeData, files, file, ignoredCodes, actions: new GithubActions() })
|
||||
|
|
Loading…
Reference in a new issue