mirror of
https://github.com/lowdefy/lowdefy.git
synced 2025-03-19 15:01:06 +08:00
fix(build): Evaluate build operators in lowdefy.yaml
This commit is contained in:
parent
c340b5237f
commit
49ed3e14fd
@ -24,7 +24,6 @@ function createSessionCallback({ authConfig, plugins }) {
|
||||
});
|
||||
|
||||
async function sessionCallback({ session, token, user }) {
|
||||
// console.log({ session, token, user });
|
||||
if (token) {
|
||||
const {
|
||||
sub,
|
||||
@ -74,6 +73,7 @@ function createSessionCallback({ authConfig, plugins }) {
|
||||
}
|
||||
|
||||
for (const plugin of sessionCallbackPlugins) {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
session = await plugin.fn({
|
||||
properties: plugin.properties ?? {},
|
||||
session,
|
||||
|
@ -16,14 +16,21 @@
|
||||
|
||||
import recursiveBuild from './recursiveBuild.js';
|
||||
import makeRefDefinition from './makeRefDefinition.js';
|
||||
// TODO: build operators aren't evaluated in lowdefy.yaml file. Move recursive call up a layer or something.
|
||||
import evaluateBuildOperators from './evaluateBuildOperators.js';
|
||||
|
||||
async function buildRefs({ context }) {
|
||||
const components = await recursiveBuild({
|
||||
const refDef = makeRefDefinition('lowdefy.yaml');
|
||||
let components = await recursiveBuild({
|
||||
context,
|
||||
refDef: makeRefDefinition('lowdefy.yaml'),
|
||||
refDef,
|
||||
count: 0,
|
||||
});
|
||||
return components || {};
|
||||
components = await evaluateBuildOperators({
|
||||
context,
|
||||
input: components,
|
||||
refDef,
|
||||
});
|
||||
return components ?? {};
|
||||
}
|
||||
|
||||
export default buildRefs;
|
||||
|
@ -19,6 +19,12 @@ import { jest } from '@jest/globals';
|
||||
import buildRefs from './buildRefs.js';
|
||||
import testContext from '../../test/testContext.js';
|
||||
|
||||
const mockLogWarn = jest.fn();
|
||||
|
||||
const logger = {
|
||||
warn: mockLogWarn,
|
||||
};
|
||||
|
||||
const readConfigFileMockImplementation = (files) => {
|
||||
const mockImp = (filePath) => {
|
||||
const file = files.find((file) => file.path === filePath);
|
||||
@ -33,6 +39,7 @@ const readConfigFileMockImplementation = (files) => {
|
||||
const mockReadConfigFile = jest.fn();
|
||||
|
||||
const context = testContext({
|
||||
logger,
|
||||
readConfigFile: mockReadConfigFile,
|
||||
});
|
||||
|
||||
@ -1047,3 +1054,91 @@ _ref: target`,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Evaluate build time operators', () => {
|
||||
test('Evaluate build time operators in lowdefy.yaml', async () => {
|
||||
const files = [
|
||||
{
|
||||
path: 'lowdefy.yaml',
|
||||
content: `
|
||||
answer:
|
||||
_build.sum:
|
||||
- 1
|
||||
- 1`,
|
||||
},
|
||||
];
|
||||
mockReadConfigFile.mockImplementation(readConfigFileMockImplementation(files));
|
||||
const res = await buildRefs({ context });
|
||||
expect(res).toEqual({
|
||||
answer: 2,
|
||||
});
|
||||
});
|
||||
|
||||
test('Evaluate build time operators in referenced file', async () => {
|
||||
const files = [
|
||||
{
|
||||
path: 'lowdefy.yaml',
|
||||
content: `
|
||||
answer:
|
||||
_ref: file.yaml`,
|
||||
},
|
||||
{
|
||||
path: 'file.yaml',
|
||||
content: `
|
||||
_build.sum:
|
||||
- 1
|
||||
- 1`,
|
||||
},
|
||||
];
|
||||
mockReadConfigFile.mockImplementation(readConfigFileMockImplementation(files));
|
||||
const res = await buildRefs({ context });
|
||||
expect(res).toEqual({
|
||||
answer: 2,
|
||||
});
|
||||
});
|
||||
|
||||
test('Build time operator error in lowdefy.yaml', async () => {
|
||||
const files = [
|
||||
{
|
||||
path: 'lowdefy.yaml',
|
||||
content: `
|
||||
answer:
|
||||
_build.sum: A`,
|
||||
},
|
||||
];
|
||||
mockReadConfigFile.mockImplementation(readConfigFileMockImplementation(files));
|
||||
const res = await buildRefs({ context });
|
||||
expect(res).toEqual({
|
||||
answer: null,
|
||||
});
|
||||
expect(mockLogWarn.mock.calls).toEqual([
|
||||
['Build operator errors.'],
|
||||
['Operator Error: _sum takes an array type as input. Received: "A" at lowdefy.yaml.'],
|
||||
]);
|
||||
});
|
||||
|
||||
test('Build time operator error in referenced file', async () => {
|
||||
const files = [
|
||||
{
|
||||
path: 'lowdefy.yaml',
|
||||
content: `
|
||||
answer:
|
||||
_ref: file.yaml`,
|
||||
},
|
||||
{
|
||||
path: 'file.yaml',
|
||||
content: `
|
||||
_build.sum: A`,
|
||||
},
|
||||
];
|
||||
mockReadConfigFile.mockImplementation(readConfigFileMockImplementation(files));
|
||||
const res = await buildRefs({ context });
|
||||
expect(res).toEqual({
|
||||
answer: null,
|
||||
});
|
||||
expect(mockLogWarn.mock.calls).toEqual([
|
||||
['Build operator errors.'],
|
||||
['Operator Error: _sum takes an array type as input. Received: "A" at file.yaml.'],
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
@ -25,12 +25,8 @@ async function recursiveParseFile({ context, refDef, count, referencedFrom }) {
|
||||
throw new Error(`Maximum recursion depth of references exceeded.`);
|
||||
}
|
||||
let fileContent = await getRefContent({ context, refDef, referencedFrom });
|
||||
const parsedFileContent = await evaluateBuildOperators({
|
||||
context,
|
||||
input: fileContent,
|
||||
refDef: { path: 'lowdefy.yaml' },
|
||||
});
|
||||
const { foundRefs, fileContentBuiltRefs } = getRefsFromFile(parsedFileContent);
|
||||
|
||||
const { foundRefs, fileContentBuiltRefs } = getRefsFromFile(fileContent);
|
||||
|
||||
const parsedFiles = {};
|
||||
|
||||
@ -39,7 +35,6 @@ async function recursiveParseFile({ context, refDef, count, referencedFrom }) {
|
||||
// To do this, since foundRefs is an array of ref definitions that are in order of the
|
||||
// deepest nodes first we for loop over over foundRefs one by one, awaiting each result.
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
for (const newRefDef of foundRefs.values()) {
|
||||
// Parse vars and path before passing down to parse new file
|
||||
const parsedRefDef = populateRefs({
|
||||
@ -55,19 +50,20 @@ async function recursiveParseFile({ context, refDef, count, referencedFrom }) {
|
||||
referencedFrom: refDef.path,
|
||||
});
|
||||
|
||||
const evaluatedOperators = await evaluateBuildOperators({
|
||||
const transformedFile = await runTransformer({
|
||||
context,
|
||||
input: parsedFile,
|
||||
refDef: parsedRefDef,
|
||||
});
|
||||
|
||||
const transformedFile = await runTransformer({
|
||||
// Evaluated in recursive loop for better error messages
|
||||
const evaluatedOperators = await evaluateBuildOperators({
|
||||
context,
|
||||
input: evaluatedOperators,
|
||||
input: transformedFile,
|
||||
refDef: parsedRefDef,
|
||||
});
|
||||
|
||||
parsedFiles[newRefDef.id] = transformedFile;
|
||||
parsedFiles[newRefDef.id] = evaluatedOperators;
|
||||
}
|
||||
return populateRefs({
|
||||
toPopulate: fileContentBuiltRefs,
|
||||
|
@ -17,15 +17,18 @@
|
||||
import { serializer, type } from '@lowdefy/helpers';
|
||||
|
||||
class NodeParser {
|
||||
constructor({ env, payload, secrets, user, operators }) {
|
||||
constructor({ env, payload, secrets, user, operators, verbose }) {
|
||||
this.env = env;
|
||||
this.operators = operators;
|
||||
this.payload = payload;
|
||||
this.secrets = secrets;
|
||||
this.user = user;
|
||||
this.parse = this.parse.bind(this);
|
||||
this.verbose;
|
||||
}
|
||||
|
||||
// TODO: Look at logging here
|
||||
// TODO: Remove console.error = () => {}; from tests
|
||||
parse({ args, input, location, operatorPrefix = '_' }) {
|
||||
if (type.isUndefined(input)) {
|
||||
return { output: input, errors: [] };
|
||||
@ -63,7 +66,9 @@ class NodeParser {
|
||||
return res;
|
||||
} catch (e) {
|
||||
errors.push(e);
|
||||
console.error(e);
|
||||
if (this.verbose) {
|
||||
console.error(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
@ -17,8 +17,6 @@
|
||||
/* eslint-disable max-classes-per-file */
|
||||
import NodeParser from './nodeParser.js';
|
||||
|
||||
console.error = () => {};
|
||||
|
||||
const args = [{ args: true }];
|
||||
|
||||
const operators = {
|
||||
|
Loading…
x
Reference in New Issue
Block a user