chore: CE changes for module input autocomplete (#28221)
This commit is contained in:
parent
cc01f7b1c9
commit
68df2a18a6
|
|
@ -12,7 +12,7 @@ import moment from "moment";
|
|||
import type { DerivedPropertiesMap } from "WidgetProvider/factory";
|
||||
import type { WidgetFeatures } from "utils/WidgetFeatures";
|
||||
import type { WidgetProps } from "../widgets/BaseWidget";
|
||||
import type { ExtraDef } from "utils/autocomplete/dataTreeTypeDefCreator";
|
||||
import type { ExtraDef } from "utils/autocomplete/defCreatorUtils";
|
||||
import type { WidgetEntityConfig } from "@appsmith/entities/DataTree/types";
|
||||
import type {
|
||||
WidgetQueryConfig,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import type { ExtraDef } from "utils/autocomplete/dataTreeTypeDefCreator";
|
||||
import { generateTypeDef } from "utils/autocomplete/dataTreeTypeDefCreator";
|
||||
import type { ExtraDef } from "utils/autocomplete/defCreatorUtils";
|
||||
import { generateTypeDef } from "utils/autocomplete/defCreatorUtils";
|
||||
import type { AppsmithEntity } from "@appsmith/entities/DataTree/types";
|
||||
import _ from "lodash";
|
||||
import { EVALUATION_PATH } from "utils/DynamicBindingUtils";
|
||||
|
|
|
|||
140
app/client/src/ce/utils/autocomplete/entityDefGeneratorMap.ts
Normal file
140
app/client/src/ce/utils/autocomplete/entityDefGeneratorMap.ts
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
import {
|
||||
type WidgetEntityConfig,
|
||||
type JSActionEntityConfig,
|
||||
type WidgetEntity,
|
||||
type ActionEntity,
|
||||
type AppsmithEntity,
|
||||
type JSActionEntity,
|
||||
ENTITY_TYPE_VALUE,
|
||||
} from "@appsmith/entities/DataTree/types";
|
||||
import type {
|
||||
ConfigTree,
|
||||
DataTreeEntity,
|
||||
} from "entities/DataTree/dataTreeTypes";
|
||||
import { isFunction } from "lodash";
|
||||
import { entityDefinitions } from "@appsmith/utils/autocomplete/EntityDefinitions";
|
||||
import type { Def } from "tern";
|
||||
import type { DataTreeDefEntityInformation } from "utils/autocomplete/CodemirrorTernService";
|
||||
import WidgetFactory from "WidgetProvider/factory";
|
||||
import {
|
||||
addSettersToDefinitions,
|
||||
generateJSFunctionTypeDef,
|
||||
generateTypeDef,
|
||||
flattenDef,
|
||||
} from "utils/autocomplete/defCreatorUtils";
|
||||
|
||||
export type EntityMap = Map<string, DataTreeDefEntityInformation>;
|
||||
|
||||
interface DefGeneratorProps {
|
||||
entity: DataTreeEntity;
|
||||
configTree: ConfigTree;
|
||||
entityName: string;
|
||||
extraDefsToDefine: Def;
|
||||
entityMap: EntityMap;
|
||||
def: Def;
|
||||
jsData: Record<string, unknown>;
|
||||
}
|
||||
|
||||
export type EntityDefGeneratorMap = Record<
|
||||
string,
|
||||
(props: DefGeneratorProps) => void
|
||||
>;
|
||||
|
||||
export const entityDefGeneratorMap: EntityDefGeneratorMap = {
|
||||
[ENTITY_TYPE_VALUE.ACTION]: (props) => {
|
||||
const { def, entity, entityMap, entityName, extraDefsToDefine } = props;
|
||||
def[entityName] = entityDefinitions.ACTION(
|
||||
entity as ActionEntity,
|
||||
extraDefsToDefine,
|
||||
);
|
||||
flattenDef(def, entityName);
|
||||
entityMap.set(entityName, {
|
||||
type: ENTITY_TYPE_VALUE.ACTION,
|
||||
subType: "ACTION",
|
||||
});
|
||||
},
|
||||
[ENTITY_TYPE_VALUE.APPSMITH]: (props) => {
|
||||
const { def, entity, entityMap, extraDefsToDefine } = props;
|
||||
def.appsmith = entityDefinitions.APPSMITH(
|
||||
entity as AppsmithEntity,
|
||||
extraDefsToDefine,
|
||||
);
|
||||
entityMap.set("appsmith", {
|
||||
type: ENTITY_TYPE_VALUE.APPSMITH,
|
||||
subType: ENTITY_TYPE_VALUE.APPSMITH,
|
||||
});
|
||||
},
|
||||
[ENTITY_TYPE_VALUE.JSACTION]: (props) => {
|
||||
const {
|
||||
configTree,
|
||||
def,
|
||||
entity,
|
||||
entityMap,
|
||||
entityName,
|
||||
extraDefsToDefine,
|
||||
jsData,
|
||||
} = props;
|
||||
const entityConfig = configTree[entityName] as JSActionEntityConfig;
|
||||
const metaObj = entityConfig.meta;
|
||||
const jsPropertiesDef: Def = {};
|
||||
|
||||
for (const funcName in metaObj) {
|
||||
const funcTypeDef = generateJSFunctionTypeDef(
|
||||
jsData,
|
||||
`${entityName}.${funcName}`,
|
||||
extraDefsToDefine,
|
||||
);
|
||||
jsPropertiesDef[funcName] = funcTypeDef;
|
||||
// To also show funcName.data in autocompletion hint, we explictly add it here
|
||||
jsPropertiesDef[`${funcName}.data`] = funcTypeDef.data;
|
||||
}
|
||||
|
||||
for (let i = 0; i < entityConfig?.variables?.length; i++) {
|
||||
const varKey = entityConfig?.variables[i];
|
||||
const varValue = (entity as JSActionEntity)[varKey];
|
||||
jsPropertiesDef[varKey] = generateTypeDef(varValue, extraDefsToDefine);
|
||||
}
|
||||
|
||||
def[entityName] = jsPropertiesDef;
|
||||
entityMap.set(entityName, {
|
||||
type: ENTITY_TYPE_VALUE.JSACTION,
|
||||
subType: "JSACTION",
|
||||
});
|
||||
},
|
||||
[ENTITY_TYPE_VALUE.WIDGET]: (props) => {
|
||||
const {
|
||||
configTree,
|
||||
def,
|
||||
entity,
|
||||
entityMap,
|
||||
entityName,
|
||||
extraDefsToDefine,
|
||||
} = props;
|
||||
const widgetType = (entity as WidgetEntity).type;
|
||||
const autocompleteDefinitions =
|
||||
WidgetFactory.getAutocompleteDefinitions(widgetType);
|
||||
|
||||
if (autocompleteDefinitions) {
|
||||
const entityConfig = configTree[entityName] as WidgetEntityConfig;
|
||||
|
||||
if (isFunction(autocompleteDefinitions)) {
|
||||
def[entityName] = autocompleteDefinitions(
|
||||
entity as WidgetEntity,
|
||||
extraDefsToDefine,
|
||||
entityConfig,
|
||||
);
|
||||
} else {
|
||||
def[entityName] = autocompleteDefinitions;
|
||||
}
|
||||
|
||||
addSettersToDefinitions(def[entityName] as Def, entity, entityConfig);
|
||||
|
||||
flattenDef(def, entityName);
|
||||
|
||||
entityMap.set(entityName, {
|
||||
type: ENTITY_TYPE_VALUE.WIDGET,
|
||||
subType: widgetType,
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
@ -0,0 +1 @@
|
|||
export * from "ce/utils/autocomplete/entityDefGeneratorMap";
|
||||
|
|
@ -7,7 +7,7 @@ import type { EntityDefinitionsOptions } from "@appsmith/utils/autocomplete/Enti
|
|||
import { isFunction } from "lodash";
|
||||
import type { Def } from "tern";
|
||||
import WidgetFactory from "WidgetProvider/factory";
|
||||
import { addSettersToDefinitions } from "utils/autocomplete/dataTreeTypeDefCreator";
|
||||
import { addSettersToDefinitions } from "utils/autocomplete/defCreatorUtils";
|
||||
|
||||
export const getWidgetChildrenPeekData = (
|
||||
widgetName: string,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import type { Def } from "tern";
|
||||
import type { TruthyPrimitiveTypes } from "utils/TypeHelpers";
|
||||
import { generateTypeDef } from "./dataTreeTypeDefCreator";
|
||||
import { generateTypeDef } from "./defCreatorUtils";
|
||||
|
||||
export type AdditionalDynamicDataTree = Record<
|
||||
string,
|
||||
|
|
|
|||
|
|
@ -1,9 +1,4 @@
|
|||
import {
|
||||
generateTypeDef,
|
||||
dataTreeTypeDefCreator,
|
||||
flattenDef,
|
||||
getFunctionsArgsType,
|
||||
} from "utils/autocomplete/dataTreeTypeDefCreator";
|
||||
import { dataTreeTypeDefCreator } from "utils/autocomplete/dataTreeTypeDefCreator";
|
||||
import type {
|
||||
WidgetEntity,
|
||||
WidgetEntityConfig,
|
||||
|
|
@ -15,6 +10,11 @@ import {
|
|||
|
||||
import InputWidget from "widgets/InputWidgetV2";
|
||||
import { registerWidgets } from "WidgetProvider/factory/registrationHelper";
|
||||
import {
|
||||
flattenDef,
|
||||
generateTypeDef,
|
||||
getFunctionsArgsType,
|
||||
} from "./defCreatorUtils";
|
||||
|
||||
describe("dataTreeTypeDefCreator", () => {
|
||||
it("creates the right def for a widget", () => {
|
||||
|
|
|
|||
|
|
@ -1,32 +1,8 @@
|
|||
import type {
|
||||
WidgetEntityConfig,
|
||||
JSActionEntityConfig,
|
||||
WidgetEntity,
|
||||
} from "@appsmith/entities/DataTree/types";
|
||||
import type {
|
||||
ConfigTree,
|
||||
DataTree,
|
||||
DataTreeEntity,
|
||||
} from "entities/DataTree/dataTreeTypes";
|
||||
import { ENTITY_TYPE_VALUE } from "entities/DataTree/dataTreeFactory";
|
||||
import { uniqueId, isFunction, isObject } from "lodash";
|
||||
import { entityDefinitions } from "@appsmith/utils/autocomplete/EntityDefinitions";
|
||||
import { getType, Types } from "utils/TypeHelpers";
|
||||
import type { DataTreeEntityObject } from "@appsmith/entities/DataTree/types";
|
||||
import type { EntityMap } from "@appsmith/utils/autocomplete/entityDefGeneratorMap";
|
||||
import { entityDefGeneratorMap } from "@appsmith/utils/autocomplete/entityDefGeneratorMap";
|
||||
import type { ConfigTree, DataTree } from "entities/DataTree/dataTreeTypes";
|
||||
import type { Def } from "tern";
|
||||
import {
|
||||
isAction,
|
||||
isAppsmithEntity,
|
||||
isJSAction,
|
||||
isTrueObject,
|
||||
isWidget,
|
||||
} from "@appsmith/workers/Evaluation/evaluationUtils";
|
||||
import type { DataTreeDefEntityInformation } from "utils/autocomplete/CodemirrorTernService";
|
||||
|
||||
export type ExtraDef = Record<string, Def | string>;
|
||||
|
||||
import type { Variable } from "entities/JSCollection";
|
||||
import WidgetFactory from "WidgetProvider/factory";
|
||||
import { shouldAddSetter } from "workers/Evaluation/evaluate";
|
||||
|
||||
// Def names are encoded with information about the entity
|
||||
// This so that we have more info about them
|
||||
|
|
@ -38,82 +14,26 @@ export const dataTreeTypeDefCreator = (
|
|||
dataTree: DataTree,
|
||||
jsData: Record<string, unknown> = {},
|
||||
configTree: ConfigTree,
|
||||
): { def: Def; entityInfo: Map<string, DataTreeDefEntityInformation> } => {
|
||||
): { def: Def; entityInfo: EntityMap } => {
|
||||
// When there is a complex data type, we store it in extra def and refer to it in the def
|
||||
const extraDefsToDefine: Def = {};
|
||||
|
||||
const def: Def = {
|
||||
"!name": "DATA_TREE",
|
||||
};
|
||||
const entityMap: Map<string, DataTreeDefEntityInformation> = new Map();
|
||||
const entityMap: EntityMap = new Map();
|
||||
|
||||
Object.entries(dataTree).forEach(([entityName, entity]) => {
|
||||
if (isWidget(entity)) {
|
||||
const widgetType = entity.type;
|
||||
const autocompleteDefinitions =
|
||||
WidgetFactory.getAutocompleteDefinitions(widgetType);
|
||||
|
||||
if (autocompleteDefinitions) {
|
||||
const entityConfig = configTree[entityName] as WidgetEntityConfig;
|
||||
|
||||
if (isFunction(autocompleteDefinitions)) {
|
||||
def[entityName] = autocompleteDefinitions(
|
||||
entity as WidgetEntity,
|
||||
extraDefsToDefine,
|
||||
entityConfig,
|
||||
);
|
||||
} else {
|
||||
def[entityName] = autocompleteDefinitions;
|
||||
}
|
||||
|
||||
addSettersToDefinitions(def[entityName] as Def, entity, entityConfig);
|
||||
|
||||
flattenDef(def, entityName);
|
||||
|
||||
entityMap.set(entityName, {
|
||||
type: ENTITY_TYPE_VALUE.WIDGET,
|
||||
subType: widgetType,
|
||||
});
|
||||
}
|
||||
} else if (isAction(entity)) {
|
||||
def[entityName] = entityDefinitions.ACTION(entity, extraDefsToDefine);
|
||||
flattenDef(def, entityName);
|
||||
entityMap.set(entityName, {
|
||||
type: ENTITY_TYPE_VALUE.ACTION,
|
||||
subType: "ACTION",
|
||||
});
|
||||
} else if (isAppsmithEntity(entity)) {
|
||||
def.appsmith = entityDefinitions.APPSMITH(entity, extraDefsToDefine);
|
||||
entityMap.set("appsmith", {
|
||||
type: ENTITY_TYPE_VALUE.APPSMITH,
|
||||
subType: ENTITY_TYPE_VALUE.APPSMITH,
|
||||
});
|
||||
} else if (isJSAction(entity)) {
|
||||
const entityConfig = configTree[entityName] as JSActionEntityConfig;
|
||||
const metaObj = entityConfig.meta;
|
||||
const jsPropertiesDef: Def = {};
|
||||
|
||||
for (const funcName in metaObj) {
|
||||
const funcTypeDef = generateJSFunctionTypeDef(
|
||||
jsData,
|
||||
`${entityName}.${funcName}`,
|
||||
extraDefsToDefine,
|
||||
);
|
||||
jsPropertiesDef[funcName] = funcTypeDef;
|
||||
// To also show funcName.data in autocompletion hint, we explictly add it here
|
||||
jsPropertiesDef[`${funcName}.data`] = funcTypeDef.data;
|
||||
}
|
||||
|
||||
for (let i = 0; i < entityConfig?.variables?.length; i++) {
|
||||
const varKey = entityConfig?.variables[i];
|
||||
const varValue = entity[varKey];
|
||||
jsPropertiesDef[varKey] = generateTypeDef(varValue, extraDefsToDefine);
|
||||
}
|
||||
|
||||
def[entityName] = jsPropertiesDef;
|
||||
entityMap.set(entityName, {
|
||||
type: ENTITY_TYPE_VALUE.JSACTION,
|
||||
subType: "JSACTION",
|
||||
const entityType = (entity as DataTreeEntityObject).ENTITY_TYPE;
|
||||
if (entityType && entityDefGeneratorMap[entityType]) {
|
||||
entityDefGeneratorMap[entityType]({
|
||||
entity,
|
||||
configTree,
|
||||
entityName,
|
||||
extraDefsToDefine,
|
||||
entityMap,
|
||||
def,
|
||||
jsData,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
@ -124,137 +44,3 @@ export const dataTreeTypeDefCreator = (
|
|||
|
||||
return { def, entityInfo: entityMap };
|
||||
};
|
||||
|
||||
export function generateTypeDef(
|
||||
value: unknown,
|
||||
extraDefsToDefine?: ExtraDef,
|
||||
depth = 0,
|
||||
): Def | string {
|
||||
switch (getType(value)) {
|
||||
case Types.ARRAY: {
|
||||
const array = value as [unknown];
|
||||
if (depth > 5) {
|
||||
return `[?]`;
|
||||
}
|
||||
|
||||
const arrayElementType = generateTypeDef(
|
||||
array[0],
|
||||
extraDefsToDefine,
|
||||
depth + 1,
|
||||
);
|
||||
|
||||
if (isObject(arrayElementType)) {
|
||||
if (extraDefsToDefine) {
|
||||
const uniqueDefName = uniqueId("def_");
|
||||
extraDefsToDefine[uniqueDefName] = arrayElementType;
|
||||
return `[${uniqueDefName}]`;
|
||||
}
|
||||
return `[?]`;
|
||||
}
|
||||
return `[${arrayElementType}]`;
|
||||
}
|
||||
case Types.OBJECT: {
|
||||
const objType: Def = {};
|
||||
const object = value as Record<string, unknown>;
|
||||
Object.keys(object).forEach((k) => {
|
||||
objType[k] = generateTypeDef(object[k], extraDefsToDefine, depth);
|
||||
});
|
||||
return objType;
|
||||
}
|
||||
case Types.STRING:
|
||||
return "string";
|
||||
case Types.NUMBER:
|
||||
return "number";
|
||||
case Types.BOOLEAN:
|
||||
return "bool";
|
||||
case Types.NULL:
|
||||
case Types.UNDEFINED:
|
||||
return "?";
|
||||
default:
|
||||
return "?";
|
||||
}
|
||||
}
|
||||
|
||||
export const flattenDef = (def: Def, entityName: string): Def => {
|
||||
const flattenedDef = def;
|
||||
if (!isTrueObject(def[entityName])) return flattenedDef;
|
||||
Object.entries(def[entityName]).forEach(([key, value]) => {
|
||||
if (key.startsWith("!")) return;
|
||||
const keyIsValid = isValidVariableName(key);
|
||||
const parentCompletion = !keyIsValid
|
||||
? `${entityName}["${key}"]`
|
||||
: `${entityName}.${key}`;
|
||||
flattenedDef[parentCompletion] = value;
|
||||
if (!isTrueObject(value)) return;
|
||||
Object.entries(value).forEach(([subKey, subValue]) => {
|
||||
if (subKey.startsWith("!")) return;
|
||||
const childKeyIsValid = isValidVariableName(subKey);
|
||||
const childCompletion = !childKeyIsValid
|
||||
? `${parentCompletion}["${subKey}"]`
|
||||
: `${parentCompletion}.${subKey}`;
|
||||
flattenedDef[childCompletion] = subValue;
|
||||
});
|
||||
});
|
||||
return flattenedDef;
|
||||
};
|
||||
|
||||
const VALID_VARIABLE_NAME_REGEX = /^([a-zA-Z_$][a-zA-Z\d_$]*)$/;
|
||||
|
||||
export const isValidVariableName = (variableName: string) =>
|
||||
VALID_VARIABLE_NAME_REGEX.test(variableName);
|
||||
|
||||
export const getFunctionsArgsType = (args: Variable[]): string => {
|
||||
// skip same name args to avoiding creating invalid type
|
||||
const argNames = new Set<string>();
|
||||
// skip invalid args name
|
||||
args.forEach((arg) => {
|
||||
if (arg.name && isValidVariableName(arg.name)) argNames.add(arg.name);
|
||||
});
|
||||
const argNamesArray = [...argNames];
|
||||
const argsTypeString = argNamesArray.reduce(
|
||||
(accumulatedArgType, argName, currentIndex) => {
|
||||
switch (currentIndex) {
|
||||
case 0:
|
||||
return `${argName}: ?`;
|
||||
case 1:
|
||||
return `${accumulatedArgType}, ${argName}: ?`;
|
||||
default:
|
||||
return `${accumulatedArgType}, ${argName}: ?`;
|
||||
}
|
||||
},
|
||||
argNamesArray[0],
|
||||
);
|
||||
return argsTypeString ? `fn(${argsTypeString})` : `fn()`;
|
||||
};
|
||||
|
||||
export function generateJSFunctionTypeDef(
|
||||
jsData: Record<string, unknown> = {},
|
||||
fullFunctionName: string,
|
||||
extraDefs: ExtraDef,
|
||||
) {
|
||||
return {
|
||||
"!type": getFunctionsArgsType([]),
|
||||
data: generateTypeDef(jsData[fullFunctionName], extraDefs),
|
||||
};
|
||||
}
|
||||
|
||||
export function addSettersToDefinitions(
|
||||
definitions: Def,
|
||||
entity: DataTreeEntity,
|
||||
entityConfig?: WidgetEntityConfig,
|
||||
) {
|
||||
if (entityConfig && entityConfig.__setters) {
|
||||
const setters = Object.keys(entityConfig.__setters);
|
||||
|
||||
setters.forEach((setterName: string) => {
|
||||
const setter = entityConfig.__setters?.[setterName];
|
||||
const setterType = entityConfig.__setters?.[setterName].type;
|
||||
|
||||
if (shouldAddSetter(setter, entity)) {
|
||||
definitions[
|
||||
setterName
|
||||
] = `fn(value:${setterType}) -> +Promise[:t=[!0.<i>.:t]]`;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
144
app/client/src/utils/autocomplete/defCreatorUtils.ts
Normal file
144
app/client/src/utils/autocomplete/defCreatorUtils.ts
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
import { isTrueObject } from "@shared/ast/src/utils";
|
||||
import type { WidgetEntityConfig } from "@appsmith/entities/DataTree/types";
|
||||
import type { DataTreeEntity } from "entities/DataTree/dataTreeTypes";
|
||||
import type { Variable } from "entities/JSCollection";
|
||||
import { isObject, uniqueId } from "lodash";
|
||||
import type { Def } from "tern";
|
||||
import { Types, getType } from "utils/TypeHelpers";
|
||||
import { shouldAddSetter } from "workers/Evaluation/evaluate";
|
||||
|
||||
export type ExtraDef = Record<string, Def | string>;
|
||||
|
||||
export const flattenDef = (def: Def, entityName: string): Def => {
|
||||
const flattenedDef = def;
|
||||
if (!isTrueObject(def[entityName])) return flattenedDef;
|
||||
Object.entries(def[entityName]).forEach(([key, value]) => {
|
||||
if (key.startsWith("!")) return;
|
||||
const keyIsValid = isValidVariableName(key);
|
||||
const parentCompletion = !keyIsValid
|
||||
? `${entityName}["${key}"]`
|
||||
: `${entityName}.${key}`;
|
||||
flattenedDef[parentCompletion] = value;
|
||||
if (!isTrueObject(value)) return;
|
||||
Object.entries(value).forEach(([subKey, subValue]) => {
|
||||
if (subKey.startsWith("!")) return;
|
||||
const childKeyIsValid = isValidVariableName(subKey);
|
||||
const childCompletion = !childKeyIsValid
|
||||
? `${parentCompletion}["${subKey}"]`
|
||||
: `${parentCompletion}.${subKey}`;
|
||||
flattenedDef[childCompletion] = subValue;
|
||||
});
|
||||
});
|
||||
return flattenedDef;
|
||||
};
|
||||
|
||||
export function generateTypeDef(
|
||||
value: unknown,
|
||||
extraDefsToDefine?: ExtraDef,
|
||||
depth = 0,
|
||||
): Def | string {
|
||||
switch (getType(value)) {
|
||||
case Types.ARRAY: {
|
||||
const array = value as [unknown];
|
||||
if (depth > 5) {
|
||||
return `[?]`;
|
||||
}
|
||||
|
||||
const arrayElementType = generateTypeDef(
|
||||
array[0],
|
||||
extraDefsToDefine,
|
||||
depth + 1,
|
||||
);
|
||||
|
||||
if (isObject(arrayElementType)) {
|
||||
if (extraDefsToDefine) {
|
||||
const uniqueDefName = uniqueId("def_");
|
||||
extraDefsToDefine[uniqueDefName] = arrayElementType;
|
||||
return `[${uniqueDefName}]`;
|
||||
}
|
||||
return `[?]`;
|
||||
}
|
||||
return `[${arrayElementType}]`;
|
||||
}
|
||||
case Types.OBJECT: {
|
||||
const objType: Def = {};
|
||||
const object = value as Record<string, unknown>;
|
||||
Object.keys(object).forEach((k) => {
|
||||
objType[k] = generateTypeDef(object[k], extraDefsToDefine, depth);
|
||||
});
|
||||
return objType;
|
||||
}
|
||||
case Types.STRING:
|
||||
return "string";
|
||||
case Types.NUMBER:
|
||||
return "number";
|
||||
case Types.BOOLEAN:
|
||||
return "bool";
|
||||
case Types.NULL:
|
||||
case Types.UNDEFINED:
|
||||
return "?";
|
||||
default:
|
||||
return "?";
|
||||
}
|
||||
}
|
||||
|
||||
const VALID_VARIABLE_NAME_REGEX = /^([a-zA-Z_$][a-zA-Z\d_$]*)$/;
|
||||
|
||||
export const isValidVariableName = (variableName: string) =>
|
||||
VALID_VARIABLE_NAME_REGEX.test(variableName);
|
||||
|
||||
export const getFunctionsArgsType = (args: Variable[]): string => {
|
||||
// skip same name args to avoiding creating invalid type
|
||||
const argNames = new Set<string>();
|
||||
// skip invalid args name
|
||||
args.forEach((arg) => {
|
||||
if (arg.name && isValidVariableName(arg.name)) argNames.add(arg.name);
|
||||
});
|
||||
const argNamesArray = [...argNames];
|
||||
const argsTypeString = argNamesArray.reduce(
|
||||
(accumulatedArgType, argName, currentIndex) => {
|
||||
switch (currentIndex) {
|
||||
case 0:
|
||||
return `${argName}: ?`;
|
||||
case 1:
|
||||
return `${accumulatedArgType}, ${argName}: ?`;
|
||||
default:
|
||||
return `${accumulatedArgType}, ${argName}: ?`;
|
||||
}
|
||||
},
|
||||
argNamesArray[0],
|
||||
);
|
||||
return argsTypeString ? `fn(${argsTypeString})` : `fn()`;
|
||||
};
|
||||
|
||||
export function generateJSFunctionTypeDef(
|
||||
jsData: Record<string, unknown> = {},
|
||||
fullFunctionName: string,
|
||||
extraDefs: ExtraDef,
|
||||
) {
|
||||
return {
|
||||
"!type": getFunctionsArgsType([]),
|
||||
data: generateTypeDef(jsData[fullFunctionName], extraDefs),
|
||||
};
|
||||
}
|
||||
|
||||
export function addSettersToDefinitions(
|
||||
definitions: Def,
|
||||
entity: DataTreeEntity,
|
||||
entityConfig?: WidgetEntityConfig,
|
||||
) {
|
||||
if (entityConfig && entityConfig.__setters) {
|
||||
const setters = Object.keys(entityConfig.__setters);
|
||||
|
||||
setters.forEach((setterName: string) => {
|
||||
const setter = entityConfig.__setters?.[setterName];
|
||||
const setterType = entityConfig.__setters?.[setterName].type;
|
||||
|
||||
if (shouldAddSetter(setter, entity)) {
|
||||
definitions[
|
||||
setterName
|
||||
] = `fn(value:${setterType}) -> +Promise[:t=[!0.<i>.:t]]`;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -12,8 +12,8 @@ import {
|
|||
ResponsiveBehavior,
|
||||
} from "layoutSystems/common/utils/constants";
|
||||
import { DefaultAutocompleteDefinitions } from "widgets/WidgetUtils";
|
||||
import type { ExtraDef } from "utils/autocomplete/dataTreeTypeDefCreator";
|
||||
import { generateTypeDef } from "utils/autocomplete/dataTreeTypeDefCreator";
|
||||
import type { ExtraDef } from "utils/autocomplete/defCreatorUtils";
|
||||
import { generateTypeDef } from "utils/autocomplete/defCreatorUtils";
|
||||
import type {
|
||||
AnvilConfig,
|
||||
AutocompletionDefinitions,
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import type { WidgetState } from "widgets/BaseWidget";
|
|||
import BaseWidget from "widgets/BaseWidget";
|
||||
import IframeComponent from "../component";
|
||||
import type { IframeWidgetProps } from "../constants";
|
||||
import { generateTypeDef } from "utils/autocomplete/dataTreeTypeDefCreator";
|
||||
import { generateTypeDef } from "utils/autocomplete/defCreatorUtils";
|
||||
import { DefaultAutocompleteDefinitions } from "widgets/WidgetUtils";
|
||||
import type {
|
||||
AnvilConfig,
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ import type {
|
|||
} from "entities/AppTheming";
|
||||
import type { BatchPropertyUpdatePayload } from "actions/controlActions";
|
||||
import { isAutoHeightEnabledForWidget } from "widgets/WidgetUtils";
|
||||
import { generateTypeDef } from "utils/autocomplete/dataTreeTypeDefCreator";
|
||||
import { generateTypeDef } from "utils/autocomplete/defCreatorUtils";
|
||||
import type {
|
||||
AnvilConfig,
|
||||
AutocompletionDefinitions,
|
||||
|
|
|
|||
|
|
@ -34,8 +34,8 @@ import {
|
|||
} from "utils/DynamicBindingUtils";
|
||||
import { removeFalsyEntries } from "utils/helpers";
|
||||
import { DefaultAutocompleteDefinitions } from "widgets/WidgetUtils";
|
||||
import { generateTypeDef } from "utils/autocomplete/dataTreeTypeDefCreator";
|
||||
import type { ExtraDef } from "utils/autocomplete/dataTreeTypeDefCreator";
|
||||
import { generateTypeDef } from "utils/autocomplete/defCreatorUtils";
|
||||
import type { ExtraDef } from "utils/autocomplete/defCreatorUtils";
|
||||
import WidgetFactory from "WidgetProvider/factory";
|
||||
import type { WidgetProps, WidgetState } from "widgets/BaseWidget";
|
||||
import BaseWidget from "widgets/BaseWidget";
|
||||
|
|
|
|||
|
|
@ -46,9 +46,9 @@ import type {
|
|||
} from "widgets/TabsWidget/constants";
|
||||
import { getMetaFlexLayers, isTargetElementClickable } from "./helper";
|
||||
import { DefaultAutocompleteDefinitions } from "widgets/WidgetUtils";
|
||||
import type { ExtraDef } from "utils/autocomplete/dataTreeTypeDefCreator";
|
||||
import type { ExtraDef } from "utils/autocomplete/defCreatorUtils";
|
||||
import { LayoutSystemTypes } from "layoutSystems/types";
|
||||
import { generateTypeDef } from "utils/autocomplete/dataTreeTypeDefCreator";
|
||||
import { generateTypeDef } from "utils/autocomplete/defCreatorUtils";
|
||||
import defaultProps from "./defaultProps";
|
||||
|
||||
import IconSVG from "../icon.svg";
|
||||
|
|
|
|||
|
|
@ -41,8 +41,8 @@ import { OperatorTypes } from "../component/Constants";
|
|||
import type { TableWidgetProps } from "../constants";
|
||||
import derivedProperties from "./parseDerivedProperties";
|
||||
import { selectRowIndex, selectRowIndices } from "./utilities";
|
||||
import type { ExtraDef } from "utils/autocomplete/dataTreeTypeDefCreator";
|
||||
import { generateTypeDef } from "utils/autocomplete/dataTreeTypeDefCreator";
|
||||
import type { ExtraDef } from "utils/autocomplete/defCreatorUtils";
|
||||
import { generateTypeDef } from "utils/autocomplete/defCreatorUtils";
|
||||
|
||||
import type {
|
||||
ColumnProperties,
|
||||
|
|
|
|||
|
|
@ -119,8 +119,8 @@ import type {
|
|||
transformDataWithEditableCell,
|
||||
} from "./reactTableUtils/transformDataPureFn";
|
||||
import { getMemoiseTransformDataWithEditableCell } from "./reactTableUtils/transformDataPureFn";
|
||||
import type { ExtraDef } from "utils/autocomplete/dataTreeTypeDefCreator";
|
||||
import { generateTypeDef } from "utils/autocomplete/dataTreeTypeDefCreator";
|
||||
import type { ExtraDef } from "utils/autocomplete/defCreatorUtils";
|
||||
import { generateTypeDef } from "utils/autocomplete/defCreatorUtils";
|
||||
import type {
|
||||
AnvilConfig,
|
||||
AutocompletionDefinitions,
|
||||
|
|
|
|||
|
|
@ -119,8 +119,8 @@ import type {
|
|||
transformDataWithEditableCell,
|
||||
} from "./reactTableUtils/transformDataPureFn";
|
||||
import { getMemoiseTransformDataWithEditableCell } from "./reactTableUtils/transformDataPureFn";
|
||||
import type { ExtraDef } from "utils/autocomplete/dataTreeTypeDefCreator";
|
||||
import { generateTypeDef } from "utils/autocomplete/dataTreeTypeDefCreator";
|
||||
import type { ExtraDef } from "utils/autocomplete/defCreatorUtils";
|
||||
import { generateTypeDef } from "utils/autocomplete/defCreatorUtils";
|
||||
import type {
|
||||
AutocompletionDefinitions,
|
||||
PropertyUpdates,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user