UNPKG

@silexlabs/grapesjs-data-source

Version:
215 lines 9.29 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getContext = getContext; exports.fieldToToken = fieldToToken; exports.getCompletion = getCompletion; const dataSourceManager_1 = require("./dataSourceManager"); const state_1 = require("./state"); const token_1 = require("./token"); const utils_1 = require("../utils"); /** * Get the context of a component * This includes all parents states, data sources queryable values, values provided in the options */ function getContext(component, manager, currentStateId, hideLoopData = false) { if (!component) { console.error('Component is required for context'); throw new Error('Component is required for context'); } // Get all queryable values from all data sources const queryable = manager.cachedQueryables .map((field) => { if (!field.dataSourceId) throw new Error(`Type ${field.id} has no data source`); return fieldToToken(field); }); // Get all states in the component scope const states = []; const loopProperties = []; let parent = component; while (parent) { // Get explicitely set states states .push(...((0, state_1.getStateIds)(parent, true, parent === component ? currentStateId : undefined) .map((stateId) => { var _a; return ({ type: 'state', storedStateId: stateId, previewIndex: 8888, label: ((_a = (0, state_1.getState)(parent, stateId, true)) === null || _a === void 0 ? void 0 : _a.label) || stateId, componentId: (0, state_1.getOrCreatePersistantId)(parent), exposed: true, }); }))); // Get states from loops if (parent !== component || !hideLoopData) { // If it is a loop on the parent or if we don't hide the loop data const loopDataState = (0, state_1.getState)(parent, '__data', false); if (loopDataState) { try { const loopDataField = (0, token_1.getExpressionResultType)(loopDataState.expression, parent); if (loopDataField) { const displayName = (label) => { var _a; return `${(_a = parent.getName()) !== null && _a !== void 0 ? _a : 'Unknown'}'s ${loopDataField.label} ${label}`; }; if (loopDataField.kind === 'list') { loopProperties.push({ type: 'state', storedStateId: '__data', componentId: (0, state_1.getOrCreatePersistantId)(parent), previewIndex: loopDataField.previewIndex, exposed: false, forceKind: 'object', // FIXME: this may be a scalar label: `Loop item (${loopDataField.label})`, }, { type: 'property', propType: 'field', fieldId: 'forloop.index0', label: displayName('forloop.index0'), kind: 'scalar', typeIds: ['number'], }, { type: 'property', propType: 'field', fieldId: 'forloop.index', label: displayName('forloop.index'), kind: 'scalar', typeIds: ['number'], }); } else { console.warn('Loop item is not a list for component', parent, 'and state', loopDataState); } } else { console.warn('Loop item type not found for component', parent, 'and state', loopDataState); } } catch (_a) { console.error('Error while getting loop item for component', parent, 'and state', loopDataState); } } } // Go up to parent parent = parent.parent(); } // Get filters which accept no input const filters = manager.filters .filter(filter => { try { return filter.validate(null); } catch (e) { console.warn('Filter validate error:', e, { filter }); return false; } }); // Add a fixed value const fixedValue = (0, utils_1.getFixedToken)(''); // Return the context return [ ...queryable, ...states, ...loopProperties, ...filters, fixedValue, ]; } /** * Create a property token from a field */ function fieldToToken(field) { var _a; if (!field) throw new Error('Field is required for token'); if (!field.dataSourceId) throw new Error(`Field ${field.id} has no data source`); return Object.assign({ type: 'property', propType: 'field', fieldId: field.id, label: field.label, typeIds: field.typeIds, dataSourceId: field.dataSourceId, kind: field.kind }, (_a = (0, token_1.getTokenOptions)(field)) !== null && _a !== void 0 ? _a : {}); } function getType(typeId, dataSourceId, componentId) { const manager = (0, dataSourceManager_1.getManager)(); if (dataSourceId) { // Get the data source const dataSource = manager.dataSources .find((dataSource) => !dataSourceId || dataSource.id === dataSourceId); if (!dataSource) throw new Error(`Data source not found ${dataSourceId}`); // Get its types const types = dataSource === null || dataSource === void 0 ? void 0 : dataSource.getTypes(); // Return the requested type const type = types.find((type) => type.id === typeId); if (!type) { manager.editor.runCommand('notifications:add', { type: 'error', group: utils_1.NOTIFICATION_GROUP, message: `Type not found ${dataSourceId !== null && dataSourceId !== void 0 ? dataSourceId : ''}.${typeId}`, componentId, }); throw new Error(`Type not found ${dataSourceId !== null && dataSourceId !== void 0 ? dataSourceId : ''}.${typeId}`); } return type; } else { // No data source id: search in standard types const standardType = dataSourceManager_1.STANDARD_TYPES.find(type => type.id === typeId.toLowerCase()); if (standardType) return standardType; // No data source id: search in all types const type = (0, dataSourceManager_1.getTypes)().find(type => type.id === typeId); if (!type) throw new Error(`Unknown type ${typeId}`); return type; } } /** * Auto complete an expression * @returns a list of possible tokens to add to the expression */ function getCompletion(options) { const { component, expression, manager, rootType, currentStateId, hideLoopData } = options; if (!component) throw new Error('Component is required for completion'); if (!expression) throw new Error('Expression is required for completion'); if (expression.length === 0) { if (rootType) { const type = getType(rootType, null, component.getId()); if (!type) { console.warn('Root type not found', rootType); return []; } return type.fields .map((field) => fieldToToken(field)); } return getContext(component, manager, currentStateId, hideLoopData); } const field = (0, token_1.getExpressionResultType)(expression, component); if (!field) { console.warn('Result type not found for expression', expression); return []; } return [] // Add fields if the kind is object .concat(field.kind === 'object' ? field.typeIds // Find possible types .map((typeId) => { var _a; return getType(typeId, (_a = field.dataSourceId) !== null && _a !== void 0 ? _a : null, component.getId()); }) // Add all of their fields .flatMap((type) => { var _a; return (_a = type === null || type === void 0 ? void 0 : type.fields) !== null && _a !== void 0 ? _a : []; }) // To token .flatMap((fieldOfField) => { // const t: Type | null = this.findType(field.typeIds, field.dataSourceId) // if(!t) throw new Error(`Type ${field.typeIds} not found`) return fieldOfField.typeIds.map((typeId) => (Object.assign(Object.assign({}, fieldToToken(fieldOfField)), { typeIds: [typeId] }))); }) : []) // Add filters .concat(manager.filters // Match input type .filter((filter) => { try { return filter.validate(field); } catch (e) { console.warn('Filter validate error:', e, { filter, field }); return false; } })); } //# sourceMappingURL=completion.js.map