mirror of
https://github.com/serverless/serverless.git
synced 2026-01-18 14:58:43 +00:00
125 lines
4.0 KiB
JavaScript
125 lines
4.0 KiB
JavaScript
'use strict';
|
|
|
|
const yaml = require('yaml-ast-parser');
|
|
const BbPromise = require('bluebird');
|
|
const fs = BbPromise.promisifyAll(require('fs'));
|
|
const _ = require('lodash');
|
|
const os = require('os');
|
|
const chalk = require('chalk');
|
|
const log = require('./log/serverlessLog');
|
|
|
|
const findKeyChain = (astContent) => {
|
|
let content = astContent;
|
|
const chain = [
|
|
content.key.value,
|
|
];
|
|
while (content.parent) {
|
|
content = content.parent;
|
|
if (content.key) {
|
|
chain.push(content.key.value);
|
|
}
|
|
}
|
|
return chain.reverse().join('.');
|
|
};
|
|
|
|
const parseAST = (ymlAstContent, astObject) => {
|
|
let newAstObject = astObject || {};
|
|
if (ymlAstContent.mappings && _.isArray(ymlAstContent.mappings)) {
|
|
_.forEach(ymlAstContent.mappings, (v) => {
|
|
if (!v.value) {
|
|
const errorMessage = [
|
|
'Serverless: ',
|
|
`${chalk.red('Your serverless.yml has an invalid value with key:')} `,
|
|
`${chalk.red(`"${v.key.value}"`)}`,
|
|
].join('');
|
|
log(errorMessage);
|
|
return;
|
|
}
|
|
|
|
if (v.key.kind === 0 && v.value.kind === 0) {
|
|
newAstObject[findKeyChain(v)] = v.value;
|
|
} else if (v.key.kind === 0 && v.value.kind === 2) {
|
|
newAstObject[findKeyChain(v)] = v.value;
|
|
newAstObject = parseAST(v.value, newAstObject);
|
|
} else if (v.key.kind === 0 && v.value.kind === 3) {
|
|
newAstObject[findKeyChain(v)] = v.value;
|
|
newAstObject = parseAST(v.value, newAstObject);
|
|
}
|
|
});
|
|
} else if (ymlAstContent.items && _.isArray(ymlAstContent.items)) {
|
|
_.forEach(ymlAstContent.items, (v, i) => {
|
|
if (v.kind === 0) {
|
|
const key = `${findKeyChain(ymlAstContent.parent)}[${i}]`;
|
|
newAstObject[key] = v;
|
|
}
|
|
});
|
|
}
|
|
|
|
return newAstObject;
|
|
};
|
|
|
|
const addNewArrayItem = (ymlFile, pathInYml, newValue) =>
|
|
fs.readFileAsync(ymlFile, 'utf8').then(yamlContent => {
|
|
const astObject = parseAST(yaml.load(yamlContent));
|
|
|
|
if (astObject[pathInYml] && astObject[pathInYml].items) {
|
|
let newArray = [];
|
|
_.forEach(astObject[pathInYml].items, (v) => {
|
|
newArray.push(v.value);
|
|
});
|
|
newArray = _.union(newArray, [newValue]);
|
|
|
|
const pathInYmlArrray = pathInYml.split('.');
|
|
let newObject = JSON.stringify(newArray);
|
|
_.forEach(pathInYmlArrray.reverse(), (v) => {
|
|
newObject = `{"${v}":${newObject}}`;
|
|
});
|
|
|
|
const beginning = yamlContent.substring(0, astObject[_.head(_.split(pathInYml, '.'))]
|
|
.parent.key.startPosition);
|
|
const end = yamlContent.substring(astObject[pathInYml].endPosition, yamlContent.length);
|
|
return fs.writeFileAsync(ymlFile, `${beginning}${yaml.dump(JSON.parse(newObject))}${end}`);
|
|
}
|
|
const pathInYmlArrray = pathInYml.split('.');
|
|
let newObject = JSON.stringify([newValue]);
|
|
_.forEach(pathInYmlArrray.reverse(), (v) => {
|
|
newObject = `{"${v}":${newObject}}`;
|
|
});
|
|
const beginning = yamlContent.substring(0, yamlContent.length);
|
|
return fs.writeFileAsync(ymlFile, `${beginning}${os.EOL}${yaml.dump(JSON.parse(newObject))}`);
|
|
});
|
|
|
|
const removeExistingArrayItem = (ymlFile, pathInYml, removeValue) =>
|
|
fs.readFileAsync(ymlFile, 'utf8').then(yamlContent => {
|
|
const astObject = parseAST(yaml.load(yamlContent));
|
|
|
|
if (astObject[pathInYml] && astObject[pathInYml].items) {
|
|
const newArray = [];
|
|
let newText = '';
|
|
_.forEach(astObject[pathInYml].items, (v) => {
|
|
newArray.push(v.value);
|
|
});
|
|
_.pull(newArray, removeValue);
|
|
|
|
if (!_.isEmpty(newArray)) {
|
|
const pathInYmlArrray = pathInYml.split('.');
|
|
let newObject = JSON.stringify(newArray);
|
|
_.forEach(pathInYmlArrray.reverse(), (v) => {
|
|
newObject = `{"${v}":${newObject}}`;
|
|
});
|
|
newText = yaml.dump(JSON.parse(newObject));
|
|
}
|
|
|
|
const beginning = yamlContent.substring(0, astObject[_.head(_.split(pathInYml, '.'))]
|
|
.parent.key.startPosition);
|
|
const end = yamlContent.substring(astObject[pathInYml].endPosition, yamlContent.length);
|
|
return fs.writeFileAsync(ymlFile, `${beginning}${newText}${end}`);
|
|
}
|
|
return BbPromise.resolve();
|
|
});
|
|
|
|
module.exports = {
|
|
addNewArrayItem,
|
|
removeExistingArrayItem,
|
|
};
|