New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@elastic.io/component-build-helper

Package Overview
Dependencies
Maintainers
12
Versions
36
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@elastic.io/component-build-helper - npm Package Compare versions

Comparing version 1.1.0 to 2.0.0-alpha1

dist/src/utils.d.ts

5

dist/src/commands/detectComponentLanguage.js

@@ -6,2 +6,3 @@ "use strict";

const DockerfileGenerator_1 = require("../DockerfileGenerator");
const utils_1 = require("../utils");
;

@@ -15,3 +16,5 @@ exports.command = 'detectComponentLanguage <componentDirectoryPath>';

const { componentDirectoryPath } = argv;
const contextLoader = await ComponentContextLoader_1.ComponentContextLoader.getInstance(componentDirectoryPath);
const getFileFunction = (0, utils_1.buildGetFileFunction)(componentDirectoryPath);
const contextLoader = new ComponentContextLoader_1.ComponentContextLoader(getFileFunction);
await contextLoader.loadFilesToContext();
const generator = await DockerfileGenerator_1.DockerfileGenerator.getInstance(contextLoader);

@@ -18,0 +21,0 @@ process.stdout.write(generator.componentLanguage);

15

dist/src/commands/generateDockerfile.js

@@ -6,2 +6,3 @@ "use strict";

const ComponentContextLoader_1 = require("../ComponentContextLoader");
const utils_1 = require("../utils");
;

@@ -15,14 +16,12 @@ exports.command = 'generateDockerfile <componentDirectoryPath>';

demandOption: true,
desc: 'Use "-" to read sources from stdin'
desc: 'Component root directory'
});
exports.builder = builder;
async function handler(argv) {
// Make sure that nobody print something to the stdout by console.log function
console.log = () => { };
const { componentDirectoryPath } = argv;
let contextLoader;
if (componentDirectoryPath === '-') {
contextLoader = await ComponentContextLoader_1.ComponentContextLoader.getInstance(process.stdin);
}
else {
contextLoader = await ComponentContextLoader_1.ComponentContextLoader.getInstance(componentDirectoryPath);
}
const getFileFunction = (0, utils_1.buildGetFileFunction)(componentDirectoryPath);
const contextLoader = new ComponentContextLoader_1.ComponentContextLoader(getFileFunction);
await contextLoader.loadFilesToContext();
const generator = await DockerfileGenerator_1.DockerfileGenerator.getInstance(contextLoader);

@@ -29,0 +28,0 @@ const dockerfile = await generator.genDockerfile();

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.handler = exports.builder = exports.desc = exports.command = void 0;
const fs_1 = require("fs");
const metaloader_1 = require("../metaloader");
const utils_1 = require("../utils");
;

@@ -14,7 +14,3 @@ exports.command = 'validate <componentDirectoryPath>';

const { componentDirectoryPath } = argv;
const getFileFunction = async (fileRelativePath) => {
const filePath = fileRelativePath.replace(/^\.\/|^\//g, '');
const buffer = await fs_1.promises.readFile(`${componentDirectoryPath.replace(/\/$/g, '')}/${filePath}`);
return buffer.toString('utf-8');
};
const getFileFunction = (0, utils_1.buildGetFileFunction)(componentDirectoryPath);
await (0, metaloader_1.validateComponentJSON)(getFileFunction);

@@ -21,0 +17,0 @@ process.exit(0);

/// <reference types="node" />
import { Readable } from 'stream';
export declare enum SOURCE_INPUT_TYPE {
STREAM = 0,
DIR = 1
}
export declare abstract class ComponentContextLoader {
export declare class ComponentContextLoader {
private getFileFunction;
constructor(getFileFunction: (path: string) => Promise<Buffer>);
protected _context: {

@@ -12,6 +9,5 @@ [key: string]: string;

protected listOfFilesToLoad: string[];
abstract loadFilesToContext(): Promise<{
loadFilesToContext(): Promise<{
[key: string]: string;
}>;
static getInstance(source: string | Readable): Promise<StreamContextLoader | DirectoryContextLoader>;
get context(): {

@@ -21,15 +17,1 @@ [p: string]: string;

}
export declare class StreamContextLoader extends ComponentContextLoader {
private readonly readStream;
constructor(readStream: Readable);
loadFilesToContext(): Promise<{
[p: string]: string;
}>;
}
export declare class DirectoryContextLoader extends ComponentContextLoader {
private readonly componentDirPath;
constructor(componentDirPath: string);
loadFilesToContext(): Promise<{
[key: string]: string;
}>;
}

@@ -6,15 +6,7 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.DirectoryContextLoader = exports.StreamContextLoader = exports.ComponentContextLoader = exports.SOURCE_INPUT_TYPE = void 0;
/* eslint-disable @typescript-eslint/no-use-before-define */
const stream_1 = require("stream");
const tar_1 = __importDefault(require("tar"));
const fs_1 = require("fs");
exports.ComponentContextLoader = void 0;
const logger_1 = __importDefault(require("./logger"));
var SOURCE_INPUT_TYPE;
(function (SOURCE_INPUT_TYPE) {
SOURCE_INPUT_TYPE[SOURCE_INPUT_TYPE["STREAM"] = 0] = "STREAM";
SOURCE_INPUT_TYPE[SOURCE_INPUT_TYPE["DIR"] = 1] = "DIR";
})(SOURCE_INPUT_TYPE = exports.SOURCE_INPUT_TYPE || (exports.SOURCE_INPUT_TYPE = {}));
const metaloader_1 = require("./metaloader");
class ComponentContextLoader {
constructor() {
constructor(getFileFunction) {
this._context = {};

@@ -36,67 +28,21 @@ // List of files needed to be downloaded

];
this.getFileFunction = getFileFunction;
}
static async getInstance(source) {
let contextLoader;
if (source instanceof stream_1.Readable) {
contextLoader = new StreamContextLoader(source);
}
else {
contextLoader = new DirectoryContextLoader(source);
}
await contextLoader.loadFilesToContext();
return contextLoader;
}
get context() {
return this._context;
}
}
exports.ComponentContextLoader = ComponentContextLoader;
class StreamContextLoader extends ComponentContextLoader {
constructor(readStream) {
super();
this.readStream = readStream;
}
loadFilesToContext() {
return new Promise((resolve, reject) => {
this.readStream
.pipe(tar_1.default.list())
.on('entry', async (entry) => {
try {
// Logo must be base64 encoded
if (entry.type === 'File' && this.listOfFilesToLoad.includes(entry.path)) {
if (entry.path === 'logo.png') {
this.context[entry.path] = (await entry.concat()).toString('base64');
}
else {
this.context[entry.path] = (await entry.concat()).toString();
}
}
}
catch (e) {
reject(e);
}
})
.on('finish', () => resolve(this._context))
.on('error', reject);
});
}
}
exports.StreamContextLoader = StreamContextLoader;
class DirectoryContextLoader extends ComponentContextLoader {
constructor(componentDirPath) {
super();
this.componentDirPath = componentDirPath.replace(/\/$/, '');
}
async loadFilesToContext() {
// check that dir exists
await fs_1.promises.access(`${this.componentDirPath}/`);
await Promise.all(this.listOfFilesToLoad.map(async (filePath) => {
try {
const buffer = await fs_1.promises.readFile(`${this.componentDirPath}/${filePath}`);
if (filePath === 'logo.png') {
this._context[filePath] = buffer.toString('base64');
const buffer = await this.getFileFunction(filePath);
if (buffer) {
if (filePath === 'component.json') {
const component = JSON.parse(buffer.toString());
await (0, metaloader_1.resolveMetadataRefs)(component, this.getFileFunction);
this._context[filePath] = JSON.stringify(component);
}
else if (filePath === 'logo.png') {
this._context[filePath] = buffer.toString('base64');
}
else {
this._context[filePath] = buffer.toString();
}
}
else {
this._context[filePath] = buffer.toString();
}
}

@@ -115,3 +61,6 @@ catch (e) {

}
get context() {
return this._context;
}
}
exports.DirectoryContextLoader = DirectoryContextLoader;
exports.ComponentContextLoader = ComponentContextLoader;

@@ -0,1 +1,5 @@

/// <reference types="node" />
import { Component } from './interfaces';
declare type getFileType = (path: string) => Promise<Buffer>;
export declare function resolveMetadataRefs(component: Component, getFile: getFileType): Promise<[any[], any[]]>;
/**

@@ -6,3 +10,4 @@ *

*/
export declare function validateComponentJSON(getFile: (path: string) => Promise<string>): Promise<any>;
export declare function validateComponentJSON(getFile: getFileType): Promise<any>;
export declare function getComponentLogo(pathToComponent: string): Promise<string>;
export {};

@@ -6,3 +6,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.getComponentLogo = exports.validateComponentJSON = void 0;
exports.getComponentLogo = exports.validateComponentJSON = exports.resolveMetadataRefs = void 0;
const index_1 = require("./index");

@@ -61,2 +61,33 @@ const fs_1 = __importDefault(require("fs"));

}
async function resolveMetadataFromPath(metadata, direction, getFile) {
const fileName = metadata[direction];
if (typeof fileName === 'string') {
console.log(`Reading incoming ${fileName}`);
const data = await getFile(fileName);
console.log(`Parsing incoming ${fileName}`);
metadata[direction] = JSON.parse(data.toString());
}
}
function resolveMetadataForObjects(actions, getFile) {
const promises = [];
Object.entries(actions).forEach(([key, action]) => {
const metadata = action.metadata;
if (metadata) {
console.log('Found metadata for', key);
promises.push(resolveMetadataFromPath(metadata, 'in', getFile));
promises.push(resolveMetadataFromPath(metadata, 'out', getFile));
}
});
return Promise.all(promises);
}
function resolveMetadataRefs(component, getFile) {
const triggers = component.triggers || {};
const actions = component.actions || {};
console.log('Found %s triggers and %s actions', Object.keys(triggers).length, Object.keys(actions).length);
return Promise.all([
resolveMetadataForObjects(triggers, getFile),
resolveMetadataForObjects(actions, getFile)
]);
}
exports.resolveMetadataRefs = resolveMetadataRefs;
/**

@@ -71,33 +102,3 @@ *

console.log('Parsing incoming component.json');
const component = JSON.parse(data);
async function resolveMetadataFromPath(metadata, direction) {
const fileName = metadata[direction];
if (typeof fileName === 'string') {
console.log(`Reading incoming ${fileName}`);
const data = await getFile(fileName);
console.log(`Parsing incoming ${fileName}`);
metadata[direction] = JSON.parse(data);
}
}
function resolveMetadataForObjects(actions) {
const promises = [];
Object.entries(actions).forEach(([key, action]) => {
const metadata = action.metadata;
if (metadata) {
console.log('Found metadata for', key);
promises.push(resolveMetadataFromPath(metadata, 'in'));
promises.push(resolveMetadataFromPath(metadata, 'out'));
}
});
return Promise.all(promises);
}
function resolveMetadataRefs(component) {
const triggers = component.triggers || {};
const actions = component.actions || {};
console.log('Found %s triggers and %s actions', Object.keys(triggers).length, Object.keys(actions).length);
return Promise.all([
resolveMetadataForObjects(triggers),
resolveMetadataForObjects(actions)
]);
}
const component = JSON.parse(data.toString());
validateComponentVersion(component.version);

@@ -107,3 +108,3 @@ validateFunctionsNames(component);

validateCredentials(component);
await resolveMetadataRefs(component);
await resolveMetadataRefs(component, getFile);
return component;

@@ -110,0 +111,0 @@ }

{
"name": "@elastic.io/component-build-helper",
"version": "1.1.0",
"version": "2.0.0-alpha1",
"description": "Helpers for the component build process",

@@ -5,0 +5,0 @@ "main": "dist/src/index.js",

@@ -10,8 +10,4 @@ # component-build-helper

```
2. get base64 representation of component logo.
```shell
component_cli getComponentLogo /path/to/component/folder
```
3. generate dockerfile for component.
2. generate dockerfile for component.

@@ -24,3 +20,3 @@ ```shell

```
4. detect component language.
3. detect component language.

@@ -27,0 +23,0 @@ ```shell

@@ -7,2 +7,4 @@ import sinon, { SinonSandbox } from 'sinon';

import { ComponentContextLoader } from '../../src/ComponentContextLoader';
import { buildGetFileFunction } from '../../src/utils';
import { nodejsComponentJson } from '../fixtures/DockerfileGenerator.data';
const { expect } = chai;

@@ -22,14 +24,9 @@ chai.use(require('sinon-chai'));

describe('newInstance', () => {
it('should throw an error in case directory of component is not exists', async () => {
await expect(ComponentContextLoader.getInstance('./spec/fixtures/unexisted_dir/'))
.to.be.rejectedWith('ENOENT: no such file or directory, access \'./spec/fixtures/unexisted_dir/\'');
});
it('should load all files for nodejs component', async () => {
const contextLoader = await ComponentContextLoader.getInstance('./spec/fixtures/component/nodejs');
const componentJson = (await fsPromise.readFile('./spec/fixtures/component/nodejs/component.json')).toString();
const contextLoader = new ComponentContextLoader(buildGetFileFunction('./spec/fixtures/component/nodejs'));
await contextLoader.loadFilesToContext();
const packageJson = (await fsPromise.readFile('./spec/fixtures/component/nodejs/package.json')).toString();
const logo = (await fsPromise.readFile('./spec/fixtures/component/nodejs/logo.png')).toString('base64');
expect(contextLoader.context).to.deep.equal({
'component.json': componentJson,
'component.json': nodejsComponentJson,
'logo.png': logo,

@@ -40,3 +37,4 @@ 'package.json': packageJson

it('should load all files for gradle component', async () => {
const contextLoader = await ComponentContextLoader.getInstance('./spec/fixtures/component/gradle');
const contextLoader = new ComponentContextLoader(buildGetFileFunction('./spec/fixtures/component/gradle'));
await contextLoader.loadFilesToContext();
const componentJson = (await fsPromise.readFile('./spec/fixtures/component/gradle/component.json')).toString();

@@ -43,0 +41,0 @@ const buildGralde = (await fsPromise.readFile('./spec/fixtures/component/gradle/build.gradle')).toString();

@@ -6,13 +6,15 @@ import sinon, { SinonSandbox } from 'sinon';

import { DockerfileGenerator } from '../../src/DockerfileGenerator';
import fs, { promises as fsPromise, readFileSync } from 'fs';
import { promises as fsPromise, readFileSync } from 'fs';
import { ComponentContextLoader } from '../../src/ComponentContextLoader';
import { Readable } from 'stream';
import {
componentJsonGradleLabel,
componentJsonLabel,
componentJsonTarLabel,
gradleDockerfile,
gradleWrapperDockerfile, java11Dockerfile, java11PredefinedJdepsInfo, labelsWithSplittedLogo,
gradleWrapperDockerfile,
java11Dockerfile,
java11PredefinedJdepsInfo,
labelsWithSplittedLogo,
predefinedDockerfile
} from '../fixtures/DockerfileGenerator.data';
import { buildGetFileFunction } from '../../src/utils';

@@ -41,3 +43,4 @@ const { expect } = chai;

it('should throw an error in case unknown component type', async () => {
componentContextLoader = await ComponentContextLoader.getInstance('./spec/fixtures/component/');
componentContextLoader = new ComponentContextLoader(buildGetFileFunction('./spec/fixtures/component/'));
await componentContextLoader.loadFilesToContext();
await expect(DockerfileGenerator.getInstance(componentContextLoader))

@@ -56,3 +59,4 @@ .to.be.rejectedWith('Unknown sources type. Please make sure that you provided correct component sources');

]);
componentContextLoader = await ComponentContextLoader.getInstance('./spec/fixtures/component/nodejs/');
componentContextLoader = new ComponentContextLoader(buildGetFileFunction('./spec/fixtures/component/nodejs/'));
await componentContextLoader.loadFilesToContext();
dockerfileGenerator = await DockerfileGenerator.getInstance(componentContextLoader);

@@ -63,3 +67,4 @@ expect(dockerfileGenerator['getComponentBuildImage']()).to.be.equal('node:16-alpine');

sandbox.stub(fsPromise, 'readFile').resolves(Buffer.from('{ "dependencies": { "elasticio-sailor-nodejs": "2.2.2"} }'));
componentContextLoader = await ComponentContextLoader.getInstance('./spec/fixtures/component/nodejs');
componentContextLoader = new ComponentContextLoader(buildGetFileFunction('./spec/fixtures/component/nodejs'));
await componentContextLoader.loadFilesToContext();
dockerfileGenerator = await DockerfileGenerator.getInstance(componentContextLoader);

@@ -86,3 +91,4 @@ nock('https://nodejs.org:443', { 'encodedQueryParams': true })

it('genDockerfile should return dockerfile structure', async () => {
componentContextLoader = await ComponentContextLoader.getInstance('./spec/fixtures/component/nodejs');
componentContextLoader = new ComponentContextLoader(buildGetFileFunction('./spec/fixtures/component/nodejs'));
await componentContextLoader.loadFilesToContext();
dockerfileGenerator = await DockerfileGenerator.getInstance(componentContextLoader);

@@ -116,3 +122,4 @@ await expect(dockerfileGenerator.genDockerfile()).to.eventually.equal(

readFileStub.callThrough();
componentContextLoader = await ComponentContextLoader.getInstance(path);
componentContextLoader = new ComponentContextLoader(buildGetFileFunction(path));
await componentContextLoader.loadFilesToContext();
dockerfileGenerator = await DockerfileGenerator.getInstance(componentContextLoader);

@@ -124,53 +131,2 @@ await expect(dockerfileGenerator.genDockerfile()).to.eventually.equal(predefinedDockerfile +

});
describe('genDockerfile from tar stream', () => {
let tarStream: Readable;
beforeEach(() => {
tarStream = fs.createReadStream('./spec/fixtures/component/nodejs/tarStream');
});
it('genDockerfile should return dockerfile structure', async () => {
nock('https://nodejs.org:443', { 'encodedQueryParams': true })
.get('/dist/')
.reply(200, nodeVersions, [
'Content-Type',
'text/html'
]);
componentContextLoader = await ComponentContextLoader.getInstance(tarStream);
dockerfileGenerator = await DockerfileGenerator.getInstance(componentContextLoader);
await expect(dockerfileGenerator.genDockerfile()).to.eventually.equal(
'FROM node:15-alpine AS base\n' +
'RUN apk add --update git tini python3 make g++ && rm -rf /var/cache/apk/*\n' +
'WORKDIR /home/node\n' +
'COPY --chown=node:node . ./\n' +
'FROM base AS dependencies\n' +
'ENV LOG_OUTPUT_MODE=short\n' +
'USER node\n' +
'RUN npm config set update-notifier false\n' +
'RUN npm install --no-audit\n' +
'RUN npm test\n' +
'RUN npm prune --production\n' +
'RUN rm -rf spec* .circleci README.md LICENSE .idea\n' +
'FROM node:15-alpine AS release\n' +
`LABEL elastic.io.component=${JSON.stringify(JSON.stringify(componentJsonTarLabel))}\n` +
`LABEL elastic.io.logo="${logo}"\n` +
'WORKDIR /home/node\n' +
'COPY --from=base --chown=node:node /sbin/tini /sbin/tini\n' +
'COPY --from=dependencies --chown=node:node /home/node /home/node\n' +
'USER node\n' +
'ENTRYPOINT ["/sbin/tini", "-v", "-e", "143", "--"]');
});
it('genDockerfile should return predefined dockerfile with labels', async () => {
tarStream = fs.createReadStream('./spec/fixtures/component/nodejs-custom-dockerfile/tarStream');
nock('https://nodejs.org:443', { 'encodedQueryParams': true })
.get('/dist/')
.reply(200, nodeVersions, [
'Content-Type',
'text/html'
]);
componentContextLoader = await ComponentContextLoader.getInstance(tarStream);
dockerfileGenerator = await DockerfileGenerator.getInstance(componentContextLoader);
await expect(dockerfileGenerator.genDockerfile()).to.eventually.equal(predefinedDockerfile +
`\nLABEL elastic.io.component=${JSON.stringify(JSON.stringify(componentJsonTarLabel))}\n` +
`LABEL elastic.io.logo="${logo}"`);
});
});

@@ -181,3 +137,4 @@ it('should split long lines in the dockerfile labels', async () => {

readFileStub.callThrough();
componentContextLoader = await ComponentContextLoader.getInstance('./spec/fixtures/component/nodejs');
componentContextLoader = new ComponentContextLoader(buildGetFileFunction('./spec/fixtures/component/nodejs'));
await componentContextLoader.loadFilesToContext();
dockerfileGenerator = await DockerfileGenerator.getInstance(componentContextLoader);

@@ -201,3 +158,4 @@ expect(dockerfileGenerator['getLabels']()).to.deep.eq(labelsWithSplittedLogo);

const path = './spec/fixtures/component/nodejs';
componentContextLoader = await ComponentContextLoader.getInstance(path);
componentContextLoader = new ComponentContextLoader(buildGetFileFunction(path));
await componentContextLoader.loadFilesToContext();
dockerfileGenerator = await DockerfileGenerator.getInstance(componentContextLoader);

@@ -228,3 +186,4 @@ });

it('should install gradle in the dockerfile in case wrapper is not exists', async () => {
componentContextLoader = await ComponentContextLoader.getInstance('./spec/fixtures/component/gradle');
componentContextLoader = new ComponentContextLoader(buildGetFileFunction('./spec/fixtures/component/gradle'));
await componentContextLoader.loadFilesToContext();
dockerfileGenerator = await DockerfileGenerator.getInstance(componentContextLoader);

@@ -234,3 +193,4 @@ expect(dockerfileGenerator.genDockerfile()).to.be.equal(gradleDockerfile);

it('should use gradlew in the dockerfile', async () => {
componentContextLoader = await ComponentContextLoader.getInstance('./spec/fixtures/component/gradle-wrapper');
componentContextLoader = new ComponentContextLoader(buildGetFileFunction('./spec/fixtures/component/gradle-wrapper'));
await componentContextLoader.loadFilesToContext();
dockerfileGenerator = await DockerfileGenerator.getInstance(componentContextLoader);

@@ -240,3 +200,4 @@ expect(dockerfileGenerator.genDockerfile()).to.be.equal(gradleWrapperDockerfile);

it('genDockerfile should return dockerfile structure', async () => {
componentContextLoader = await ComponentContextLoader.getInstance('./spec/fixtures/component/gradle');
componentContextLoader = new ComponentContextLoader(buildGetFileFunction('./spec/fixtures/component/gradle'));
await componentContextLoader.loadFilesToContext();
dockerfileGenerator = await DockerfileGenerator.getInstance(componentContextLoader);

@@ -250,3 +211,4 @@ expect(dockerfileGenerator.genDockerfile()).to.be.equal(gradleDockerfile);

readFileStub.callThrough();
componentContextLoader = await ComponentContextLoader.getInstance(path);
componentContextLoader = new ComponentContextLoader(buildGetFileFunction(path));
await componentContextLoader.loadFilesToContext();
dockerfileGenerator = await DockerfileGenerator.getInstance(componentContextLoader);

@@ -263,3 +225,4 @@ await expect(dockerfileGenerator.genDockerfile()).to.be.equal(predefinedDockerfile +

readFileStub.callThrough();
componentContextLoader = await ComponentContextLoader.getInstance(path);
componentContextLoader = new ComponentContextLoader(buildGetFileFunction(path));
await componentContextLoader.loadFilesToContext();
dockerfileGenerator = await DockerfileGenerator.getInstance(componentContextLoader);

@@ -276,3 +239,4 @@ await expect(dockerfileGenerator.genDockerfile()).to.be.equal(java11Dockerfile);

readFileStub.callThrough();
componentContextLoader = await ComponentContextLoader.getInstance(path);
componentContextLoader = new ComponentContextLoader(buildGetFileFunction(path));
await componentContextLoader.loadFilesToContext();
dockerfileGenerator = await DockerfileGenerator.getInstance(componentContextLoader);

@@ -287,3 +251,4 @@ await expect(dockerfileGenerator.genDockerfile()).to.be.equal(java11PredefinedJdepsInfo);

readFileStub.callThrough();
componentContextLoader = await ComponentContextLoader.getInstance(path);
componentContextLoader = new ComponentContextLoader(buildGetFileFunction(path));
await componentContextLoader.loadFilesToContext();
await expect(DockerfileGenerator.getInstance(componentContextLoader)).to.be.rejectedWith('Unsupported Java version. Allowed values: ["1.8","11","17","18"]');

@@ -290,0 +255,0 @@ });

@@ -58,7 +58,7 @@ /* eslint-disable @typescript-eslint/camelcase */

function getFileFunction(repositoryPath: string): (path: string) => Promise<string> {
function getFileFunction(repositoryPath: string): (path: string) => Promise<Buffer> {
return (filePath: string) => {
return new Promise((resolve, reject) => {
if (components[repositoryPath + filePath]) {
return resolve(JSON.stringify(components[repositoryPath + filePath]));
return resolve(Buffer.from(JSON.stringify(components[repositoryPath + filePath])));
}

@@ -71,3 +71,3 @@ reject(new Error('File ' + filePath + ' is missing'));

it('should return promise', function () {
expect(validateComponentJSON(async () => ('')).then).to.be.instanceof(Function);
expect(validateComponentJSON(async () => (Buffer.from(''))).then).to.be.instanceof(Function);
});

@@ -74,0 +74,0 @@

import type { Arguments, CommandBuilder } from 'yargs';
import { ComponentContextLoader } from '../ComponentContextLoader';
import { DockerfileGenerator } from '../DockerfileGenerator';
import { buildGetFileFunction } from '../utils';

@@ -19,3 +20,5 @@ interface Options {

const { componentDirectoryPath } = argv;
const contextLoader = await ComponentContextLoader.getInstance(componentDirectoryPath as string);
const getFileFunction = buildGetFileFunction(componentDirectoryPath as string);
const contextLoader = new ComponentContextLoader(getFileFunction);
await contextLoader.loadFilesToContext();
const generator = await DockerfileGenerator.getInstance(contextLoader);

@@ -22,0 +25,0 @@ process.stdout.write(generator.componentLanguage);

import type { Arguments, CommandBuilder } from 'yargs';
import { DockerfileGenerator } from '../DockerfileGenerator';
import { ComponentContextLoader } from '../ComponentContextLoader';
import { buildGetFileFunction } from '../utils';

@@ -20,12 +21,11 @@ interface Options {

demandOption: true,
desc: 'Use "-" to read sources from stdin' });
desc: 'Component root directory' });
export async function handler(argv: Arguments<Options>) {
// Make sure that nobody print something to the stdout by console.log function
console.log = () => {};
const { componentDirectoryPath } = argv;
let contextLoader: ComponentContextLoader;
if (componentDirectoryPath === '-') {
contextLoader = await ComponentContextLoader.getInstance(process.stdin);
} else {
contextLoader = await ComponentContextLoader.getInstance(componentDirectoryPath as string);
}
const getFileFunction = buildGetFileFunction(componentDirectoryPath as string);
const contextLoader = new ComponentContextLoader(getFileFunction);
await contextLoader.loadFilesToContext();
const generator = await DockerfileGenerator.getInstance(contextLoader);

@@ -32,0 +32,0 @@ const dockerfile = await generator.genDockerfile();

import type { Arguments, CommandBuilder } from 'yargs';
import { promises } from 'fs';
import { validateComponentJSON } from '../metaloader';
import { buildGetFileFunction } from '../utils';

@@ -19,9 +19,5 @@ interface Options {

const { componentDirectoryPath } = argv;
const getFileFunction = async (fileRelativePath: string) => {
const filePath = fileRelativePath.replace(/^\.\/|^\//g, '');
const buffer = await promises.readFile(`${(componentDirectoryPath as string).replace(/\/$/g, '')}/${filePath}`);
return buffer.toString('utf-8');
};
const getFileFunction = buildGetFileFunction(componentDirectoryPath as string);
await validateComponentJSON(getFileFunction);
process.exit(0);
};

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

/* eslint-disable @typescript-eslint/no-use-before-define */
import { Readable } from 'stream';
import tar, { ReadEntry } from 'tar';
import { promises as fsPromise } from 'fs';
import logger from './logger';
export enum SOURCE_INPUT_TYPE { STREAM, DIR }
import { resolveMetadataRefs } from './metaloader';
export abstract class ComponentContextLoader {
export class ComponentContextLoader {
private getFileFunction: (path: string) => Promise<Buffer>;
constructor(getFileFunction: (path: string) => Promise<Buffer>) {
this.getFileFunction = getFileFunction;
}
protected _context: { [key: string]: string } = {}

@@ -26,70 +27,16 @@

abstract loadFilesToContext(): Promise<{ [key: string]: string }>;
static async getInstance(source: string | Readable) {
let contextLoader;
if (source instanceof Readable) {
contextLoader = new StreamContextLoader(source);
} else {
contextLoader = new DirectoryContextLoader(source);
}
await contextLoader.loadFilesToContext();
return contextLoader;
}
get context(): { [p: string]: string } {
return this._context;
}
}
export class StreamContextLoader extends ComponentContextLoader {
private readonly readStream: Readable;
constructor(readStream: Readable) {
super();
this.readStream = readStream;
}
loadFilesToContext(): Promise<{ [p: string]: string }> {
return new Promise((resolve, reject) => {
this.readStream
.pipe(tar.list())
.on('entry', async (entry: ReadEntry) => {
try {
// Logo must be base64 encoded
if (entry.type === 'File' && this.listOfFilesToLoad.includes(entry.path)) {
if (entry.path === 'logo.png') {
this.context[entry.path] = (await entry.concat()).toString('base64');
} else {
this.context[entry.path] = (await entry.concat()).toString();
}
}
} catch (e) {
reject(e);
}
})
.on('finish', () => resolve(this._context))
.on('error', reject);
});
}
}
export class DirectoryContextLoader extends ComponentContextLoader {
private readonly componentDirPath: string;
constructor(componentDirPath: string) {
super();
this.componentDirPath = componentDirPath.replace(/\/$/, '');
}
async loadFilesToContext(): Promise<{ [key: string]: string }> {
// check that dir exists
await fsPromise.access(`${this.componentDirPath}/`);
async loadFilesToContext() {
await Promise.all(this.listOfFilesToLoad.map(async (filePath) => {
try {
const buffer = await fsPromise.readFile(`${this.componentDirPath}/${filePath}`);
if (filePath === 'logo.png') {
this._context[filePath] = buffer.toString('base64');
} else {
this._context[filePath] = buffer.toString();
const buffer = await this.getFileFunction(filePath);
if (buffer) {
if (filePath === 'component.json') {
const component = JSON.parse(buffer.toString());
await resolveMetadataRefs(component, this.getFileFunction);
this._context[filePath] = JSON.stringify(component);
} else if (filePath === 'logo.png') {
this._context[filePath] = buffer.toString('base64');
} else {
this._context[filePath] = buffer.toString();
}
}

@@ -107,2 +54,6 @@ } catch (e) {

}
get context(): { [p: string]: string } {
return this._context;
}
}

@@ -67,2 +67,41 @@ import { Action, Component, Metadata } from './interfaces';

declare type getFileType = (path: string) => Promise<Buffer>;
async function resolveMetadataFromPath(metadata: Metadata, direction: 'in'|'out', getFile: getFileType) {
const fileName = metadata[direction];
if (typeof fileName === 'string') {
console.log(`Reading incoming ${fileName}`);
const data = await getFile(fileName);
console.log(`Parsing incoming ${fileName}`);
metadata[direction] = JSON.parse(data.toString());
}
}
function resolveMetadataForObjects(actions: { [action: string]: Action }, getFile: getFileType) {
const promises: Promise<any>[] = [];
Object.entries(actions).forEach(([key, action]) => {
const metadata = action.metadata;
if (metadata) {
console.log('Found metadata for', key);
promises.push(resolveMetadataFromPath(metadata, 'in', getFile));
promises.push(resolveMetadataFromPath(metadata, 'out', getFile));
}
});
return Promise.all(promises);
}
export function resolveMetadataRefs(component: Component, getFile: getFileType) {
const triggers = component.triggers || {};
const actions = component.actions || {};
console.log('Found %s triggers and %s actions',
Object.keys(triggers).length,
Object.keys(actions).length);
return Promise.all([
resolveMetadataForObjects(triggers, getFile),
resolveMetadataForObjects(actions, getFile)
]);
}
/**

@@ -73,45 +112,8 @@ *

*/
export async function validateComponentJSON(getFile: (path: string) => Promise<string>) {
export async function validateComponentJSON(getFile: getFileType) {
console.log('Reading incoming component.json');
const data = await getFile('./component.json');
console.log('Parsing incoming component.json');
const component = JSON.parse(data);
const component = JSON.parse(data.toString());
async function resolveMetadataFromPath(metadata: Metadata, direction: 'in'|'out') {
const fileName = metadata[direction];
if (typeof fileName === 'string') {
console.log(`Reading incoming ${fileName}`);
const data = await getFile(fileName);
console.log(`Parsing incoming ${fileName}`);
metadata[direction] = JSON.parse(data);
}
}
function resolveMetadataForObjects(actions: { [action: string]: Action }) {
const promises: Promise<any>[] = [];
Object.entries(actions).forEach(([key, action]) => {
const metadata = action.metadata;
if (metadata) {
console.log('Found metadata for', key);
promises.push(resolveMetadataFromPath(metadata, 'in'));
promises.push(resolveMetadataFromPath(metadata, 'out'));
}
});
return Promise.all(promises);
}
function resolveMetadataRefs(component: Component) {
const triggers = component.triggers || {};
const actions = component.actions || {};
console.log('Found %s triggers and %s actions',
Object.keys(triggers).length,
Object.keys(actions).length);
return Promise.all([
resolveMetadataForObjects(triggers),
resolveMetadataForObjects(actions)
]);
}
validateComponentVersion(component.version);

@@ -121,3 +123,3 @@ validateFunctionsNames(component);

validateCredentials(component);
await resolveMetadataRefs(component);
await resolveMetadataRefs(component, getFile);
return component;

@@ -124,0 +126,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