safer & more explicit implementation of variableResolvesrs(also renamed)

This commit is contained in:
Daniel Schep 2019-08-21 10:22:05 -04:00
parent 55a794f4e0
commit c3674e1293
4 changed files with 34 additions and 15 deletions

View File

@ -213,13 +213,15 @@ class EchoTestVarPlugin {
getDependentEchoTestValue(src) {
return src.slice(5);
}
// if a variable type depends on profile/stage/region/credentials, to avoid infinite loops in
// trying to resolve variables that depend on themselves, specify as such by setting a
// dependendServiceName property on the variable getter
getDependentEchoTestValue.dependendServiceName = 'StateDependentEcho'
this.variableGetters = {
this.variableResolvers = {
echo: this.getEchoTestValue,
echoStageDependent: getDependentEchoTestValue
// if a variable type depends on profile/stage/region/credentials, to avoid infinite loops in
// trying to resolve variables that depend on themselves, specify as such by setting a
// dependendServiceName property on the variable getter
echoStageDependent: : {
resolver: this.getDependentEchoTestValue,
serviceName: 'echo that isnt prepopulated',
isDisabledAtPrepopulation: true
};
}
}

View File

@ -311,19 +311,36 @@ class PluginManager {
}
loadVariableGetters(pluginInstance) {
for (const [variablePrefix, variableGetter] of _.entries(
pluginInstance.variableGetters || {}
for (const [variablePrefix, resolverOrOptions] of _.entries(
pluginInstance.variableResolvers || {}
)) {
this.serverless.variables.customVariableResolverFuncs[variablePrefix] = variableGetter.bind(
let options = resolverOrOptions;
if (typeof resolverOrOptions === 'function') {
options = {
resolver: resolverOrOptions,
};
}
this.serverless.variables.customVariableResolverFuncs[variablePrefix] = options.resolver.bind(
this.serverless.variables
);
if (
this.serverless.variables.variableResolvers
.filter(([, , custom]) => custom)
.map(([, funcName]) => funcName)
.includes(variablePrefix)
) {
throw new Error(
`Plugin ${pluginInstance.constructor.name} is trying to add support for $\{${variablePrefix}:} variables but another plugin already added it`
);
}
this.serverless.variables.variableResolvers.push([
new RegExp(`^${variablePrefix}:`),
variablePrefix,
true,
]);
if (variableGetter.dependentServiceName) {
if (options.isDisabledAtPrepopulation) {
this.serverless.variables.dependentServices.push({
name: variableGetter.dependentServiceName,
name: options.serviceName,
method: variablePrefix,
custom: true,
});

View File

@ -1045,7 +1045,7 @@ describe('PluginManager', () => {
return Promise.resolve('testVariable');
}
constructor() {
this.variableGetters = {
this.variableResolvers = {
test: this.getTestVariable,
};
}
@ -1058,7 +1058,7 @@ describe('PluginManager', () => {
pluginManager.loadVariableGetters(pluginInstance);
expect(pluginManager.serverless.variables.variableResolvers).to.deep.equal([
[/^test:/, 'test'],
[/^test:/, 'test', true],
]);
expect(
Object.keys(pluginManager.serverless.variables.customVariableResolverFuncs)

View File

@ -552,9 +552,9 @@ class Variables {
if (this.tracker.contains(variableString)) {
ret = this.tracker.get(variableString, propertyString);
} else {
for (const [regex, getter] of this.variableResolvers) {
for (const [regex, getter, custom] of this.variableResolvers) {
if (variableString.match(regex)) {
if (this[getter]) {
if (!custom) {
ret = this[getter].bind(this)(variableString);
} else {
ret = this.customVariableResolverFuncs[getter](variableString);