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

@serverless/platform-client

Package Overview
Dependencies
Maintainers
7
Versions
159
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@serverless/platform-client - npm Package Compare versions

Comparing version 3.2.0 to 3.3.0

4

package.json
{
"name": "@serverless/platform-client",
"version": "3.2.0",
"version": "3.3.0",
"main": "./src/index.js",

@@ -15,3 +15,2 @@ "jsdelivr": "dist-web/serverless-platform-client.min.js",

"archiver": "^5.0.0",
"fast-glob": "^3.2.4",
"axios": "^0.21.1",

@@ -25,3 +24,2 @@ "https-proxy-agent": "^5.0.0",

"querystring": "^0.2.0",
"run-parallel-limit": "^1.0.6",
"throat": "^5.0.0",

@@ -28,0 +26,0 @@ "traverse": "^0.6.6",

@@ -7,25 +7,9 @@ 'use strict';

const crypto = require('crypto');
const path = require('path');
const fs = require('fs');
const Axios = require('axios');
const { tmpdir } = require('os');
const axios = require('axios');
const exec = require('child_process').exec;
const utils = require('./utils');
const fg = require('fast-glob');
const AdmZip = require('adm-zip');
const runParallelLimit = require('run-parallel-limit');
// Create a new axios instance and make sure we clear the default axios headers
// as they cause a mismatch with the signature provided by aws
const axios = Axios.create();
axios.defaults.headers.common = {};
axios.defaults.headers.put = {};
axios.defaults.headers.get = {};
// make sure axios handles large packages
const axiosConfig = {
maxContentLength: Infinity,
maxBodyLength: Infinity,
};
/**

@@ -236,172 +220,49 @@ * Correctly formats an instanceId

const log = (msg = '') => console.log(msg); // eslint-disable-line
const getFilesToUpload = (map = {}, previousMap = {}, options) => {
const filesToUpload = [];
if (options.force) {
return Object.keys(map);
/*
* Uploads the component instance src input reference if available
*/
const preRunSrcUpload = async (sdk, orgName, inputs) => {
const packagePath = path.join(tmpdir(), `${Math.random().toString(36).substring(6)}.zip`);
const { srcOriginal } = inputs;
let { src } = inputs;
let exclude = [];
if (typeof srcOriginal === 'object' && srcOriginal.exclude) {
exclude = srcOriginal.exclude;
}
Object.keys(map).forEach((filePath) => {
if (!previousMap[filePath] || previousMap[filePath] !== map[filePath]) {
filesToUpload.push(filePath);
}
});
return filesToUpload;
};
const getFilesToDelete = (map = {}, previousMap = {}) => {
const filesToDelete = [];
Object.keys(previousMap).forEach((filePath) => {
if (!map[filePath]) {
filesToDelete.push(filePath);
}
});
return filesToDelete;
};
const getPreviousMap = async (previousMapDownloadUrl) => {
try {
return (await axios.get(previousMapDownloadUrl, null, axiosConfig)).data;
} catch (e) {
return undefined;
}
};
const preCache = async (sdk, { orgName, stageName, appName, instanceName }, options) => {
// console.time('preCache');
const res = await utils.request({
endpoint: `${sdk.getDomain('engine')}/preCache`,
// Get the package signed urls. This is an object includes both the upload and download urls
// the upload url is used to upload the package to s3
// while the download url is passed to the component instannce to be downnloaded in the lambda runtime
const packageUrls = await utils.request({
endpoint: `${sdk.getDomain('engine')}/getUploadUrls`,
accessKey: sdk.accessKey,
method: 'POST',
data: { orgName, stageName, appName, instanceName },
data: {
orgName,
},
});
if (!options.force) {
res.previousMap = await getPreviousMap(res.previousMapDownloadUrl);
}
// Zip source
await utils.zip(src, { outputFilePath: packagePath, exclude });
// console.timeEnd('preCache');
// Create a new axios instance and make sure we clear the default axios headers
// as they cause a mismatch with the signature provided by aws
const request = axios.create();
request.defaults.headers.common = {};
request.defaults.headers.put = {};
const body = fs.readFileSync(packagePath);
return res;
};
// Make sure axios handles large packages
const config = {
maxContentLength: Infinity,
maxBodyLength: Infinity,
};
const getFilesAndMap = async (inputs) => {
// console.time('getFilesAndMap');
const { srcOriginal } = inputs;
const { src } = inputs;
let exclude = []; // todo should we add anything here by default? ie. README.md (.git ? -Doug)
if (typeof srcOriginal === 'object' && srcOriginal.exclude) {
exclude = exclude.concat(srcOriginal.exclude);
}
await request.put(packageUrls.upload, body, config);
const files = {};
const map = {};
// eslint-disable-next-line
await new Promise(async (resolve, reject) => {
const filesPaths = await fg('**/*', { cwd: src, ignore: exclude });
const tasks = filesPaths.map((filePath) => {
return (callback) => {
const absoluteFilePath = path.resolve(src, filePath);
fs.readFile(absoluteFilePath, (err, file) => {
if (err) {
callback(err);
return;
}
files[filePath] = {
file,
stat: {},
};
// this fixes this potential permissions issue:
// https://github.com/serverless/components/issues/687
// commenting out for now until we actually face it to save on ms
// files[filePath].stat = fs.statSync(absoluteFilePath);
map[filePath] = crypto.createHash('md5').update(file).digest('hex');
callback();
});
};
});
runParallelLimit(tasks, 2048, (err) => {
if (err) {
reject(err);
} else {
resolve();
}
});
});
// console.timeEnd('getFilesAndMap');
return { map, files };
// replace the src input to point to the download url so that it's download in the lambda runtime
src = packageUrls.download;
return src;
};
const zipChanges = async (filesToUpload, filesToDelete, map, files) => {
if (filesToUpload.length === 0 && filesToDelete.length === 0) {
return null;
}
const zip = new AdmZip();
if (filesToDelete.length !== 0) {
const filesToDeleteContent = JSON.stringify(filesToDelete);
zip.addFile('deleted.files', Buffer.alloc(filesToDeleteContent.length, filesToDeleteContent));
}
const mapContent = JSON.stringify(map);
zip.addFile('src.map', Buffer.alloc(mapContent.length, mapContent));
for (const filePath of filesToUpload) {
const mode = files[filePath].stat.mode & 0o100 ? 0o755 : 0o644;
zip.addFile(filePath, files[filePath].file, null, mode);
}
return zip.toBuffer();
};
const cache = async (sdk, instance, options) => {
// console.time('total');
const [{ map, files }, { previousMap, changesUploadUrl, srcDownloadUrl }] = await Promise.all([
getFilesAndMap(instance.inputs),
preCache(sdk, instance, options),
]);
const filesToUpload = getFilesToUpload(map, previousMap, options);
const filesToDelete = getFilesToDelete(map, previousMap, options);
if (filesToUpload.length !== 0 || filesToDelete.length !== 0) {
options.cacheOutdated = true;
// log(`Updating ${filesToUpload.length} files`);
// log(`Deleting ${filesToDelete.length} files`);
// console.time('zipping');
const zipBuffer = await zipChanges(filesToUpload, filesToDelete, map, files);
// console.timeEnd('zipping');
// console.time('uploading');
await axios.put(changesUploadUrl, zipBuffer, axiosConfig);
// console.timeEnd('uploading');
} else {
options.cacheOutdated = false;
// log('No changes detected.');
}
// console.timeEnd('total');
return srcDownloadUrl;
};
/**

@@ -450,8 +311,4 @@ * Run a method. "inputs" override serverless.yml inputs and should only be provided when using custom methods.

// this should eventually move to the CLI
if (process.argv.includes('--force')) {
options.force = true;
}
instance.inputs.src = await cache(sdk, instance, options);
// Upload the "inputs.src" code
instance.inputs.src = await preRunSrcUpload(sdk, instance.orgName, instance.inputs);
}

@@ -458,0 +315,0 @@

Sorry, the diff of this file is too big to display

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