Skip to content

Commit

Permalink
feat(builtins): refactor , and plugins
Browse files Browse the repository at this point in the history
  • Loading branch information
manushak committed Sep 19, 2024
1 parent 3d37db2 commit 9dddd5d
Show file tree
Hide file tree
Showing 3 changed files with 160 additions and 397 deletions.
173 changes: 41 additions & 132 deletions src/if-run/builtins/coefficient/index.ts
Original file line number Diff line number Diff line change
@@ -1,143 +1,52 @@
import {z, ZodType} from 'zod';

import {
ERRORS,
evaluateInput,
evaluateConfig,
evaluateArithmeticOutput,
getParameterFromArithmeticExpression,
validateArithmeticExpression,
} from '@grnsft/if-core/utils';
import {
mapConfigIfNeeded,
mapOutputIfNeeded,
} from '@grnsft/if-core/utils/helpers';
import {
CoefficientConfig,
ExecutePlugin,
MappingParams,
PluginParametersMetadata,
PluginParams,
} from '@grnsft/if-core/types';
import {z} from 'zod';
import {PluginFactory} from '@grnsft/if-core/interfaces';
import {ConfigParams, PluginParams} from '@grnsft/if-core/types';

import {validate} from '../../../common/util/validations';

import {STRINGS} from '../../config';

const {ConfigError} = ERRORS;
const {MISSING_CONFIG} = STRINGS;
export const Coefficient = PluginFactory({
metadata: {
inputs: {},
outputs: {},
},
configValidation: z.object({
coefficient: z.number(),
'input-parameter': z.string().min(1),
'output-parameter': z.string().min(1),
}),
inputValidation: (input: PluginParams, config: ConfigParams) => {
const inputData = {
'input-parameter': input[config['input-parameter']],
};
const validationSchema = z.record(z.string(), z.number());
validate(validationSchema, inputData);

export const Coefficient = (
config: CoefficientConfig,
parametersMetadata: PluginParametersMetadata,
mapping: MappingParams
): ExecutePlugin => {
const metadata = {
kind: 'execute',
inputs: parametersMetadata?.inputs,
outputs: parametersMetadata?.outputs,
};
return input;
},
implementation: async (inputs: PluginParams[], config: ConfigParams = {}) => {
const inputParameter = config['input-parameter'];
const outputParameter = config['output-parameter'];
const coefficient = config['coefficient'];

/**
* Calculate the product of each input parameter.
*/
const execute = (inputs: PluginParams[]) => {
const safeConfig = validateConfig();
const {
'input-parameter': inputParameter,
'output-parameter': outputParameter,
} = safeConfig;
return inputs.map(input => {
const calculatedConfig = evaluateConfig({
config: safeConfig,
input,
parametersToEvaluate: ['input-parameter', 'coefficient'],
});

const safeInput = validateSingleInput(input, inputParameter);
const coefficient = Number(calculatedConfig['coefficient']);
const calculatedResult = calculateProduct(
safeInput,
calculatedConfig['input-parameter'],
coefficient
);

const result = {
...input,
...safeInput,
...evaluateArithmeticOutput(outputParameter, calculatedResult),
[outputParameter]: calculateProduct(input, inputParameter, coefficient),
};

return mapOutputIfNeeded(result, mapping);
return result;
});
};

/**
* Checks for required fields in input.
*/
const validateSingleInput = (
input: PluginParams,
configInputParameter: string
) => {
const inputParameter =
getParameterFromArithmeticExpression(configInputParameter);
const evaluatedInput = evaluateInput(input);

const inputData = {
[inputParameter]: evaluatedInput[inputParameter],
};
const validationSchema = z.record(z.string(), z.number());
validate(validationSchema, inputData);

return evaluatedInput;
};

/**
* Calculates the product of the energy components.
*/
const calculateProduct = (
input: PluginParams,
inputParameter: string | number,
coefficient: number
) =>
(isNaN(Number(inputParameter)) ? input[inputParameter] : inputParameter) *
coefficient;

/**
* Checks config value are valid.
*/
const validateConfig = () => {
if (!config) {
throw new ConfigError(MISSING_CONFIG);
}

const mappedConfig = mapConfigIfNeeded(config, mapping);

const configSchema = z
.object({
coefficient: z.preprocess(
value => validateArithmeticExpression('coefficient', value),
z.number()
),
'input-parameter': z.string().min(1),
'output-parameter': z.string().min(1),
})
.refine(params => {
Object.entries(params).forEach(([param, value]) =>
validateArithmeticExpression(param, value)
);

return true;
});

return validate<z.infer<typeof configSchema>>(
configSchema as ZodType<any>,
mappedConfig
);
};

return {
metadata,
execute,
};
};
},
allowArithmeticExpressions: ['input-parameter', 'coefficient'],
});

/**
* Calculates the product of the energy components.
*/
const calculateProduct = (
input: PluginParams,
inputParameter: string | number,
coefficient: number
) =>
(isNaN(Number(inputParameter)) ? input[inputParameter] : inputParameter) *
coefficient;
195 changes: 61 additions & 134 deletions src/if-run/builtins/divide/index.ts
Original file line number Diff line number Diff line change
@@ -1,110 +1,27 @@
import {z} from 'zod';
import {
ERRORS,
evaluateInput,
evaluateConfig,
evaluateArithmeticOutput,
validateArithmeticExpression,
getParameterFromArithmeticExpression,
} from '@grnsft/if-core/utils';
import {
mapConfigIfNeeded,
mapOutputIfNeeded,
} from '@grnsft/if-core/utils/helpers';
import {
ExecutePlugin,
PluginParams,
ConfigParams,
PluginParametersMetadata,
MappingParams,
} from '@grnsft/if-core/types';
import {PluginFactory} from '@grnsft/if-core/interfaces';
import {ConfigParams, PluginParams} from '@grnsft/if-core/types';

import {validate} from '../../../common/util/validations';

import {STRINGS} from '../../config';

const {ConfigError, MissingInputDataError} = ERRORS;
const {MISSING_CONFIG, MISSING_INPUT_DATA, ZERO_DIVISION} = STRINGS;

export const Divide = (
config: ConfigParams,
parametersMetadata: PluginParametersMetadata,
mapping: MappingParams
): ExecutePlugin => {
const metadata = {
kind: 'execute',
inputs: parametersMetadata?.inputs,
outputs: parametersMetadata?.outputs,
};

/**
* Calculate the division of each input parameter.
*/
const execute = (inputs: PluginParams[]) => {
const safeConfig = validateConfig();
const {numerator, denominator, output} = safeConfig;

return inputs.map((input, index) => {
const evaluatedConfig = evaluateConfig({
config: safeConfig,
input,
parametersToEvaluate: ['numerator', 'denominator'],
});
const safeInput = validateSingleInput(input, safeConfig);
const calculatedResult = calculateDivide(safeInput, index, {
numerator: evaluatedConfig.numerator || numerator,
denominator: evaluatedConfig.denominator || denominator,
});
import {ERRORS} from '@grnsft/if-core/utils';

const result = {
...input,
...safeInput,
...evaluateArithmeticOutput(output, calculatedResult),
};

return mapOutputIfNeeded(result, mapping);
});
};

/**
* Checks config value are valid.
*/
const validateConfig = () => {
if (!config) {
throw new ConfigError(MISSING_CONFIG);
}

const mappedConfig = mapConfigIfNeeded(config, mapping);
const schema = z
.object({
numerator: z.string().min(1),
denominator: z.string().or(z.number()),
output: z.string(),
})
.refine(params => {
Object.entries(params).forEach(([param, value]) =>
validateArithmeticExpression(param, value)
);

return true;
});

return validate<z.infer<typeof schema>>(schema, mappedConfig);
};
import {STRINGS} from '../../config';

/**
* Checks for required fields in input.
*/
const validateSingleInput = (
input: PluginParams,
safeConfig: ConfigParams
) => {
const numerator = getParameterFromArithmeticExpression(
safeConfig.numerator
);
const denominator = getParameterFromArithmeticExpression(
safeConfig.denominator
);
const {MissingInputDataError} = ERRORS;
const {MISSING_INPUT_DATA, ZERO_DIVISION} = STRINGS;
export const Divide = PluginFactory({
metadata: {
inputs: {},
outputs: {},
},
configValidation: z.object({
numerator: z.string().min(1),
denominator: z.string().or(z.number()),
output: z.string(),
}),
inputValidation: (input: PluginParams, config: ConfigParams) => {
const {numerator, denominator} = config;

const schema = z
.object({
Expand All @@ -119,39 +36,49 @@ export const Divide = (
return true;
});

const evaluatedInput = evaluateInput(input);
return validate<z.infer<typeof schema>>(schema, evaluatedInput);
};
return validate<z.infer<typeof schema>>(schema, input);
},
implementation: async (inputs: PluginParams[], config: ConfigParams) => {
const {numerator, denominator, output} = config;

/**
* Calculates the division of the given parameter.
*/
const calculateDivide = (
input: PluginParams,
index: number,
params: {
numerator: number | string;
denominator: number | string;
}
) => {
const {denominator, numerator} = params;
const finalDenominator =
typeof denominator === 'number'
? denominator
: input[denominator] || denominator;
const finalNumerator =
typeof numerator === 'number' ? numerator : input[numerator];

if (finalDenominator === 0) {
console.warn(ZERO_DIVISION(Divide.name, index));
return finalNumerator;
}

return finalNumerator / finalDenominator;
};
return inputs.map((input, index) => {
const calculatedResult = calculateDivide(input, index, {
numerator: input.numerator || numerator,
denominator: input.denominator || denominator,
});

return {
metadata,
execute,
};
return {
...input,
[output]: calculatedResult,
};
});
},
allowArithmeticExpressions: ['numerator', 'denominator'],
});

/**
* Calculates the division of the given parameter.
*/
const calculateDivide = (
input: PluginParams,
index: number,
params: {
numerator: number | string;
denominator: number | string;
}
) => {
const {denominator, numerator} = params;
const finalDenominator =
typeof denominator === 'number'
? denominator
: input[denominator] || denominator;
const finalNumerator =
typeof numerator === 'number' ? numerator : input[numerator];

if (finalDenominator === 0) {
console.warn(ZERO_DIVISION(Divide.name, index));
return finalNumerator;
}

return finalNumerator / finalDenominator;
};
Loading

0 comments on commit 9dddd5d

Please sign in to comment.