Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Export CEL Format #989

Closed
wants to merge 19 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions packages/core/modules/export/cel.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {
} from "../utils/stuff";
import { defaultConjunction } from "../utils/defaultUtils";
import { List, Map } from "immutable";
import { spelEscape } from "../utils/export";
import { celEscape } from "../utils/export";

export const celFormat = (tree, config) => {
return _celFormat(tree, config, false);
Expand Down Expand Up @@ -210,8 +210,8 @@ const formatRule = (item, config, meta) => {
}

//format field
const formattedField
= fieldSrc == "func"
const formattedField =
fieldSrc == "func"
? formatFunc(meta, config, field)
: formatField(meta, config, field);
if (formattedField == undefined) return undefined;
Expand Down Expand Up @@ -285,9 +285,9 @@ const formatValue = (
ret = fn.call(config.ctx, ...args);
} else {
if (Array.isArray(currentValue)) {
ret = currentValue.map((v) => spelEscape(v));
ret = currentValue.map((v) => celEscape(v));
} else {
ret = spelEscape(currentValue);
ret = celEscape(currentValue);
}
}
}
Expand Down Expand Up @@ -365,9 +365,9 @@ const formatFunc = (meta, config, currentValue) => {
}
let formattedDefaultVal;
if (
formattedArgVal === undefined
&& !isOptional
&& defaultValue != undefined
formattedArgVal === undefined &&
!isOptional &&
defaultValue != undefined
) {
formattedDefaultVal = formatValue(
meta,
Expand Down
111 changes: 93 additions & 18 deletions packages/core/modules/utils/export.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ const spelInlineList = (vals, toArray = false) => {
javaType = jt;
} else if (javaType != jt) {
if (
numberJavaTypes.includes(javaType)
&& numberJavaTypes.includes(jt)
numberJavaTypes.includes(javaType) &&
numberJavaTypes.includes(jt)
) {
// found int and float in collecton - use float
javaType = "float";
Expand All @@ -95,9 +95,9 @@ const spelInlineList = (vals, toArray = false) => {
// build inline list or array
let res;
if (toArray) {
res = `new ${javaType}[][${escapedVals.join(", ")}]`;
res = `new ${javaType}[]{${escapedVals.join(", ")}}`;
} else {
res = `[${escapedVals.join(", ")}]`;
res = `{${escapedVals.join(", ")}}`;
}

return res;
Expand All @@ -119,20 +119,20 @@ export const spelEscape = (
return "null";
}
switch (typeof val) {
case "boolean":
return val ? "true" : "false";
case "number":
if (!Number.isFinite(val) || isNaN(val)) return undefined;
return val + (!Number.isInteger(val) || numberToFloat ? "f" : "");
case "object":
if (Array.isArray(val)) {
return spelInlineList(val, arrayToArray);
} else {
// see `spelFormatValue` for Date, LocalTime
throw new Error("spelEscape: Object is not supported");
}
default:
return spelEscapeString(val);
case "boolean":
return val ? "true" : "false";
case "number":
if (!Number.isFinite(val) || isNaN(val)) return undefined;
return val + (!Number.isInteger(val) || numberToFloat ? "f" : "");
case "object":
if (Array.isArray(val)) {
return spelInlineList(val, arrayToArray);
} else {
// see `spelFormatValue` for Date, LocalTime
throw new Error("spelEscape: Object is not supported");
}
default:
return spelEscapeString(val);
}
};

Expand Down Expand Up @@ -187,3 +187,78 @@ export const spelImportConcat = (val) => {
};

export const stringifyForDisplay = (v) => (v == null ? "NULL" : v.toString());

const celInlineList = (vals, toArray = false) => {
// find java type of values
let javaType;
let jt;
const numberJavaTypes = ["int", "float"];
vals.map((v) => {
if (v !== undefined && v !== null) {
if (typeof v === "string") {
jt = "String";
} else if (typeof v === "number") {
jt = Number.isInteger(v) ? "int" : "float";
} else throw new Error(`celEscape: Can't use value ${v} in array`);

if (!javaType) {
javaType = jt;
} else if (javaType != jt) {
if (
numberJavaTypes.includes(javaType) &&
numberJavaTypes.includes(jt)
) {
// found int and float in collecton - use float
javaType = "float";
} else
throw new Error(
`celEscape: Can't use different types in array: found ${javaType} and ${jt}`
);
}
}
});
if (!javaType) {
javaType = "String"; //default if empty array
}

// for floats we should add 'f' to all items
let escapedVals;
if (javaType == "float") {
escapedVals = vals.map((v) => celEscape(v, true));
} else {
escapedVals = vals.map((v) => celEscape(v));
}

// build inline list or array
let res;
if (toArray) {
res = `new ${javaType}[][${escapedVals.join(", ")}]`;
} else {
res = `[${escapedVals.join(", ")}]`;
}

return res;
};

export const celEscape = (val, numberToFloat = false, arrayToArray = false) => {
// https://docs.spring.io/spring-framework/docs/3.2.x/spring-framework-reference/html/expressions.html#expressions-ref-literal
if (val === undefined || val === null) {
return "null";
}
switch (typeof val) {
case "boolean":
return val ? "true" : "false";
case "number":
if (!Number.isFinite(val) || isNaN(val)) return undefined;
return val + (!Number.isInteger(val) || numberToFloat ? "f" : "");
case "object":
if (Array.isArray(val)) {
return celInlineList(val, arrayToArray);
} else {
// see `spelFormatValue` for Date, LocalTime
throw new Error("celEscape: Object is not supported");
}
default:
return spelEscapeString(val);
}
};