ddf-query-validator
Advanced tools
Comparing version 1.3.0 to 1.3.1
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const isNil = require("lodash.isnil"); | ||
const includes = require("lodash.includes"); | ||
const get = require("lodash.get"); | ||
const helper_service_1 = require("./helper.service"); | ||
var tslib_1 = require("tslib"); | ||
var isNil = require("lodash.isnil"); | ||
var includes = require("lodash.includes"); | ||
var get = require("lodash.get"); | ||
var helper_service_1 = require("./helper.service"); | ||
function getRepositoryPath(basePath, queryParam) { | ||
const { dataset, branch, commit } = queryParam; | ||
return `${basePath}${dataset}/${branch}/${commit}`; | ||
var dataset = queryParam.dataset, branch = queryParam.branch, commit = queryParam.commit; | ||
return "" + basePath + dataset + "/" + branch + "/" + commit; | ||
} | ||
exports.getRepositoryPath = getRepositoryPath; | ||
function getFilePath(repositoryPath, filePath = 'datapackage.json') { | ||
return `${repositoryPath}/${filePath}`; | ||
function getFilePath(repositoryPath, filePath) { | ||
if (filePath === void 0) { filePath = 'datapackage.json'; } | ||
return repositoryPath + "/" + filePath; | ||
} | ||
exports.getFilePath = getFilePath; | ||
function extendQueryWithRepository(queryParam, config = {}) { | ||
const REPOSITORY_DESCRIPTORS = get(config, 'repositoryDescriptors', {}); | ||
const IS_DEFAULT_DATASET = isNil(queryParam.dataset); | ||
function extendQueryWithRepository(queryParam, config) { | ||
if (config === void 0) { config = {}; } | ||
var REPOSITORY_DESCRIPTORS = get(config, 'repositoryDescriptors', {}); | ||
var IS_DEFAULT_DATASET = isNil(queryParam.dataset); | ||
if (!IS_DEFAULT_DATASET) { | ||
const [originDataset, originBranch] = queryParam.dataset.split('#'); | ||
var _a = tslib_1.__read(queryParam.dataset.split('#'), 2), originDataset = _a[0], originBranch = _a[1]; | ||
if (!queryParam.branch && originBranch) { | ||
@@ -26,20 +29,20 @@ queryParam.branch = originBranch; | ||
} | ||
const IS_DEFAULT_BRANCH = isNil(queryParam.branch); | ||
const IS_DEFAULT_COMMIT = isNil(queryParam.commit); | ||
const { dataset = get(config, 'defaultRepository', helper_service_1.DEFAULT_REPOSITORY_NAME), branch = get(config, 'defaultRepositoryBranch', helper_service_1.DEFAULT_REPOSITORY_BRANCH) } = queryParam; | ||
var IS_DEFAULT_BRANCH = isNil(queryParam.branch); | ||
var IS_DEFAULT_COMMIT = isNil(queryParam.commit); | ||
var _b = queryParam.dataset, dataset = _b === void 0 ? get(config, 'defaultRepository', helper_service_1.DEFAULT_REPOSITORY_NAME) : _b, _c = queryParam.branch, branch = _c === void 0 ? get(config, 'defaultRepositoryBranch', helper_service_1.DEFAULT_REPOSITORY_BRANCH) : _c; | ||
if (isNil(REPOSITORY_DESCRIPTORS[dataset])) { | ||
throw new Error(`No ${printDataset(dataset, IS_DEFAULT_DATASET)} was found`); | ||
throw new Error("No " + printDataset(dataset, IS_DEFAULT_DATASET) + " was found"); | ||
} | ||
if (isNil(REPOSITORY_DESCRIPTORS[dataset][branch])) { | ||
throw new Error(`No ${printBranch(branch, IS_DEFAULT_BRANCH)} in ${printDataset(dataset, IS_DEFAULT_DATASET)} was found`); | ||
throw new Error("No " + printBranch(branch, IS_DEFAULT_BRANCH) + " in " + printDataset(dataset, IS_DEFAULT_DATASET) + " was found"); | ||
} | ||
if (queryParam.commit === 'HEAD') { | ||
queryParam.commit = get(REPOSITORY_DESCRIPTORS, `${dataset}.${branch}.0`) || get(config, 'defaultRepositoryCommit', helper_service_1.DEFAULT_REPOSITORY_HASH); | ||
queryParam.commit = get(REPOSITORY_DESCRIPTORS, dataset + "." + branch + ".0") || get(config, 'defaultRepositoryCommit', helper_service_1.DEFAULT_REPOSITORY_HASH); | ||
} | ||
const { commit = get(REPOSITORY_DESCRIPTORS, `${dataset}.${branch}.0`) || get(config, 'defaultRepositoryCommit', helper_service_1.DEFAULT_REPOSITORY_HASH) } = queryParam; | ||
var _d = queryParam.commit, commit = _d === void 0 ? get(REPOSITORY_DESCRIPTORS, dataset + "." + branch + ".0") || get(config, 'defaultRepositoryCommit', helper_service_1.DEFAULT_REPOSITORY_HASH) : _d; | ||
if (!includes(REPOSITORY_DESCRIPTORS[dataset][branch], commit)) { | ||
throw new Error(`No ${printCommit(commit, IS_DEFAULT_COMMIT)} in ${printDefault(IS_DEFAULT_BRANCH)}branch '${branch}' in ${printDataset(dataset, IS_DEFAULT_DATASET)} was found`); | ||
throw new Error("No " + printCommit(commit, IS_DEFAULT_COMMIT) + " in " + printDefault(IS_DEFAULT_BRANCH) + "branch '" + branch + "' in " + printDataset(dataset, IS_DEFAULT_DATASET) + " was found"); | ||
} | ||
const repositoryPath = getRepositoryPath('', { dataset, branch, commit }); | ||
Object.assign(queryParam, { repositoryPath }); | ||
var repositoryPath = getRepositoryPath('', { dataset: dataset, branch: branch, commit: commit }); | ||
Object.assign(queryParam, { repositoryPath: repositoryPath }); | ||
} | ||
@@ -51,10 +54,10 @@ exports.extendQueryWithRepository = extendQueryWithRepository; | ||
function printDataset(dataset, IS_DEFAULT_DATASET) { | ||
return `${printDefault(IS_DEFAULT_DATASET)}dataset '${dataset}'`; | ||
return printDefault(IS_DEFAULT_DATASET) + "dataset '" + dataset + "'"; | ||
} | ||
function printBranch(branch, IS_DEFAULT_BRANCH) { | ||
return `${printDefault(IS_DEFAULT_BRANCH)}branch '${branch}'`; | ||
return printDefault(IS_DEFAULT_BRANCH) + "branch '" + branch + "'"; | ||
} | ||
function printCommit(commit, IS_DEFAULT_COMMIT) { | ||
return `${printDefault(IS_DEFAULT_COMMIT)}commit '${commit}'`; | ||
return printDefault(IS_DEFAULT_COMMIT) + "commit '" + commit + "'"; | ||
} | ||
//# sourceMappingURL=dataset-manager.service.js.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const isEmpty = require("lodash.isempty"); | ||
const filter = require("lodash.filter"); | ||
const map = require("lodash.map"); | ||
const get = require("lodash.get"); | ||
const compact = require("lodash.compact"); | ||
const includes = require("lodash.includes"); | ||
const startsWith = require("lodash.startswith"); | ||
const isNil = require("lodash.isnil"); | ||
const trimStart = require("lodash.trimstart"); | ||
const flatMap = require("lodash.flatmap"); | ||
const helper_service_1 = require("./helper.service"); | ||
const util_1 = require("util"); | ||
function validateQueryDefinitions(query, options = {}) { | ||
return new Promise((resolve, reject) => { | ||
const validationResult = [ | ||
...validateSelectDefinitions(query, options), | ||
...validateWhereDefinitions(query, options), | ||
]; | ||
const isQueryValid = isEmpty(validationResult); | ||
var tslib_1 = require("tslib"); | ||
var isEmpty = require("lodash.isempty"); | ||
var filter = require("lodash.filter"); | ||
var map = require("lodash.map"); | ||
var get = require("lodash.get"); | ||
var compact = require("lodash.compact"); | ||
var includes = require("lodash.includes"); | ||
var startsWith = require("lodash.startswith"); | ||
var isNil = require("lodash.isnil"); | ||
var trimStart = require("lodash.trimstart"); | ||
var flatMap = require("lodash.flatmap"); | ||
var helper_service_1 = require("./helper.service"); | ||
var util_1 = require("util"); | ||
function validateQueryDefinitions(query, options) { | ||
if (options === void 0) { options = {}; } | ||
return new Promise(function (resolve, reject) { | ||
var validationResult = tslib_1.__spread(validateSelectDefinitions(query, options), validateWhereDefinitions(query, options)); | ||
var isQueryValid = isEmpty(validationResult); | ||
if (!isQueryValid) { | ||
return reject(`Too many query definition errors [repo: ${options.basePath}]: \n* ${validationResult.join('\n* ')}`); | ||
return reject("Too many query definition errors [repo: " + options.basePath + "]: \n* " + validationResult.join('\n* ')); | ||
} | ||
@@ -30,24 +29,24 @@ return resolve(); | ||
function validateSelectDefinitions(query, options) { | ||
const errorMessages = []; | ||
const fromClause = get(query, 'from', null); | ||
const selectClause = get(query, 'select', null); | ||
const key = get(selectClause, 'key'); | ||
const value = get(selectClause, 'value'); | ||
const ALLOWED_KEYS = []; | ||
const ALLOWED_VALUES = []; | ||
const { conceptsLookup } = options; | ||
var errorMessages = []; | ||
var fromClause = get(query, 'from', null); | ||
var selectClause = get(query, 'select', null); | ||
var key = get(selectClause, 'key'); | ||
var value = get(selectClause, 'value'); | ||
var ALLOWED_KEYS = []; | ||
var ALLOWED_VALUES = []; | ||
var conceptsLookup = options.conceptsLookup; | ||
switch (true) { | ||
case helper_service_1.isDatapointsQuery(query): | ||
const CONCEPT_TYPES_FOR_DATAPOINTS = [helper_service_1.CONCEPT_TYPE_ENTITY_SET, helper_service_1.CONCEPT_TYPE_ENTITY_DOMAIN, helper_service_1.CONCEPT_TYPE_TIME]; | ||
ALLOWED_KEYS.push(...getAllowedConceptGidsByConceptType(CONCEPT_TYPES_FOR_DATAPOINTS, conceptsLookup)); | ||
ALLOWED_VALUES.push(...conceptsLookup.keys()); | ||
var CONCEPT_TYPES_FOR_DATAPOINTS = [helper_service_1.CONCEPT_TYPE_ENTITY_SET, helper_service_1.CONCEPT_TYPE_ENTITY_DOMAIN, helper_service_1.CONCEPT_TYPE_TIME]; | ||
ALLOWED_KEYS.push.apply(ALLOWED_KEYS, tslib_1.__spread(getAllowedConceptGidsByConceptType(CONCEPT_TYPES_FOR_DATAPOINTS, conceptsLookup))); | ||
ALLOWED_VALUES.push.apply(ALLOWED_VALUES, tslib_1.__spread(conceptsLookup.keys())); | ||
break; | ||
case (helper_service_1.isEntitiesQuery(query)): | ||
const CONCEPT_TYPES_FOR_ENTITIES = [helper_service_1.CONCEPT_TYPE_ENTITY_SET, helper_service_1.CONCEPT_TYPE_ENTITY_DOMAIN]; | ||
ALLOWED_KEYS.push(...getAllowedConceptGidsByConceptType(CONCEPT_TYPES_FOR_ENTITIES, conceptsLookup)); | ||
ALLOWED_VALUES.push(...conceptsLookup.keys()); | ||
var CONCEPT_TYPES_FOR_ENTITIES = [helper_service_1.CONCEPT_TYPE_ENTITY_SET, helper_service_1.CONCEPT_TYPE_ENTITY_DOMAIN]; | ||
ALLOWED_KEYS.push.apply(ALLOWED_KEYS, tslib_1.__spread(getAllowedConceptGidsByConceptType(CONCEPT_TYPES_FOR_ENTITIES, conceptsLookup))); | ||
ALLOWED_VALUES.push.apply(ALLOWED_VALUES, tslib_1.__spread(conceptsLookup.keys())); | ||
break; | ||
case (helper_service_1.isConceptsQuery(query)): | ||
ALLOWED_KEYS.push(helper_service_1.RESERVED_CONCEPT); | ||
ALLOWED_VALUES.push(...conceptsLookup.keys(), helper_service_1.RESERVED_CONCEPT, helper_service_1.RESERVED_CONCEPT_TYPE, helper_service_1.RESERVED_DOMAIN, helper_service_1.RESERVED_UNIT, helper_service_1.RESERVED_DRILL_UP); | ||
ALLOWED_VALUES.push.apply(ALLOWED_VALUES, tslib_1.__spread(conceptsLookup.keys(), [helper_service_1.RESERVED_CONCEPT, helper_service_1.RESERVED_CONCEPT_TYPE, helper_service_1.RESERVED_DOMAIN, helper_service_1.RESERVED_UNIT, helper_service_1.RESERVED_DRILL_UP])); | ||
break; | ||
@@ -66,13 +65,13 @@ default: | ||
} | ||
const errorMessages = []; | ||
const whereClause = get(query, 'where', null); | ||
const fromClause = get(query, 'from', null); | ||
const selectClause = get(query, 'select', null); | ||
const key = get(selectClause, 'key'); | ||
const value = get(selectClause, 'value'); | ||
const operators = getWhereOperators(whereClause); | ||
const { conceptsLookup } = options; | ||
var errorMessages = []; | ||
var whereClause = get(query, 'where', null); | ||
var fromClause = get(query, 'from', null); | ||
var selectClause = get(query, 'select', null); | ||
var key = get(selectClause, 'key'); | ||
var value = get(selectClause, 'value'); | ||
var operators = getWhereOperators(whereClause); | ||
var conceptsLookup = options.conceptsLookup; | ||
switch (true) { | ||
case helper_service_1.isDatapointsQuery(query): | ||
const CONCEPT_TYPES_FOR_DATAPOINTS = []; | ||
var CONCEPT_TYPES_FOR_DATAPOINTS = []; | ||
CONCEPT_TYPES_FOR_DATAPOINTS.push(helper_service_1.CONCEPT_TYPE_ENTITY_SET, helper_service_1.CONCEPT_TYPE_ENTITY_DOMAIN, helper_service_1.CONCEPT_TYPE_TIME); | ||
@@ -87,3 +86,3 @@ errorMessages.push(); | ||
function getWhereOperators(whereClause) { | ||
const operators = {}; | ||
var operators = {}; | ||
getWhereOperatorsRecursively(whereClause, operators); | ||
@@ -93,6 +92,6 @@ return operators; | ||
function getWhereOperatorsRecursively(whereClause, operators, сandidate) { | ||
for (const field in whereClause) { | ||
const hasCandidate = !isNil(сandidate); | ||
const isCandidate = !hasCandidate && !startsWith(field, '$') && isNaN(+field); | ||
const [domain, ...set] = field.split('.'); | ||
for (var field in whereClause) { | ||
var hasCandidate = !isNil(сandidate); | ||
var isCandidate = !hasCandidate && !startsWith(field, '$') && isNaN(+field); | ||
var _a = tslib_1.__read(field.split('.')), domain = _a[0], set = _a.slice(1); | ||
if (isCandidate) { | ||
@@ -113,5 +112,5 @@ if (isNil(operators[domain])) { | ||
function checkIfSelectKeyHasInvalidDefinitions(fromClause, key, ALLOWED_KEYS) { | ||
const unavailableKeys = getUnavailableSelectItems(key, ALLOWED_KEYS); | ||
var unavailableKeys = getUnavailableSelectItems(key, ALLOWED_KEYS); | ||
if (!isEmpty(unavailableKeys)) { | ||
return `'select.key' clause for '${fromClause}' query contains unavailable item(s): ${unavailableKeys.join(', ')}`; | ||
return "'select.key' clause for '" + fromClause + "' query contains unavailable item(s): " + unavailableKeys.join(', '); | ||
} | ||
@@ -123,25 +122,25 @@ } | ||
} | ||
const fromClause = get(query, 'from', null); | ||
const unavailableValues = getUnavailableSelectItems(value, ALLOWED_VALUES); | ||
var fromClause = get(query, 'from', null); | ||
var unavailableValues = getUnavailableSelectItems(value, ALLOWED_VALUES); | ||
if (!isEmpty(value) && !isEmpty(unavailableValues)) { | ||
return `'select.value' clause for '${fromClause}' query contains unavailable item(s): ${unavailableValues.join(', ')}`; | ||
return "'select.value' clause for '" + fromClause + "' query contains unavailable item(s): " + unavailableValues.join(', '); | ||
} | ||
} | ||
function checkIfWhereHasAbsentDefinitions(fromClause, candidates, conceptsLookup) { | ||
const unavailableValues = filter(candidates, (candidate) => !conceptsLookup.has(candidate)); | ||
var unavailableValues = filter(candidates, function (candidate) { return !conceptsLookup.has(candidate); }); | ||
if (!isEmpty(unavailableValues)) { | ||
return `'where' clause for '${fromClause}' query contains unavailable item(s) that is not present in dataset: ${unavailableValues.join(', ')}`; | ||
return "'where' clause for '" + fromClause + "' query contains unavailable item(s) that is not present in dataset: " + unavailableValues.join(', '); | ||
} | ||
} | ||
function checkIfWhereHasUnavailableDimensionDefinitions(fromClause, candidates, select) { | ||
const unavailableValues = filter(candidates, (candidate) => !includes(select, candidate)); | ||
var unavailableValues = filter(candidates, function (candidate) { return !includes(select, candidate); }); | ||
if (!isEmpty(unavailableValues)) { | ||
return `'where' clause for '${fromClause}' query contains item(s) that is not present in 'select': ${unavailableValues.join(', ')}`; | ||
return "'where' clause for '" + fromClause + "' query contains item(s) that is not present in 'select': " + unavailableValues.join(', '); | ||
} | ||
} | ||
function checkIfWhereHasWrongRelativesDefinitions(fromClause, operators, conceptsLookup) { | ||
const unavailableValues = flatMap(operators, (children, parent) => { | ||
const unavailableChildren = map(children, (child) => { | ||
const childConcept = conceptsLookup.get(child); | ||
return childConcept.domain === parent || childConcept.drill_up === parent ? null : `${parent}.${child}`; | ||
var unavailableValues = flatMap(operators, function (children, parent) { | ||
var unavailableChildren = map(children, function (child) { | ||
var childConcept = conceptsLookup.get(child); | ||
return childConcept.domain === parent || childConcept.drill_up === parent ? null : parent + "." + child; | ||
}); | ||
@@ -151,12 +150,15 @@ return unavailableChildren; | ||
if (!isEmpty(unavailableValues)) { | ||
return `'where' clause for '${fromClause}' query contains item(s) that has wrong relatives: ${compact(unavailableValues).join(', ')}`; | ||
return "'where' clause for '" + fromClause + "' query contains item(s) that has wrong relatives: " + compact(unavailableValues).join(', '); | ||
} | ||
} | ||
function getUnavailableSelectItems(selectItems, ALLOWED_ITEMS) { | ||
return filter(selectItems, (value) => !includes(ALLOWED_ITEMS, value)); | ||
return filter(selectItems, function (value) { return !includes(ALLOWED_ITEMS, value); }); | ||
} | ||
function getAllowedConceptGidsByConceptType(allowedConceptTypes, conceptsLookup) { | ||
const filteredAllowedConcepts = filter([...conceptsLookup.values()], ({ concept_type }) => includes(allowedConceptTypes, concept_type)); | ||
var filteredAllowedConcepts = filter(tslib_1.__spread(conceptsLookup.values()), function (_a) { | ||
var concept_type = _a.concept_type; | ||
return includes(allowedConceptTypes, concept_type); | ||
}); | ||
return map(filteredAllowedConcepts, 'concept'); | ||
} | ||
//# sourceMappingURL=definition.service.js.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const keys = require("lodash.keys"); | ||
const isObject = require("lodash.isobject"); | ||
const head = require("lodash.head"); | ||
const helper_service_1 = require("./helper.service"); | ||
const interfaces_1 = require("./interfaces"); | ||
var tslib_1 = require("tslib"); | ||
var keys = require("lodash.keys"); | ||
var isObject = require("lodash.isobject"); | ||
var head = require("lodash.head"); | ||
var helper_service_1 = require("./helper.service"); | ||
var interfaces_1 = require("./interfaces"); | ||
function isWhereClauseBasedOnConjunction(query) { | ||
@@ -19,24 +20,28 @@ if (!helper_service_1.isDatapointsQuery(query)) { | ||
isWhereClauseBasedOnConjunction, | ||
(query, conceptsLookup) => { | ||
function (query, conceptsLookup) { | ||
var e_1, _a; | ||
if (!isWhereClauseBasedOnConjunction(query)) { | ||
return null; | ||
} | ||
for (const whereAndClauseDetail of query.where.$and) { | ||
const whereAndClauseDetailKeys = keys(whereAndClauseDetail); | ||
if (whereAndClauseDetailKeys.length === 1) { | ||
const whereAndClauseDetailKey = head(whereAndClauseDetailKeys); | ||
const whereAndClauseDetailValue = whereAndClauseDetail[whereAndClauseDetailKey]; | ||
if (query.join && query.join[whereAndClauseDetailValue]) { | ||
const joinClausePart = query.join[whereAndClauseDetailValue]; | ||
const joinClausePartWhere = joinClausePart.where; | ||
const joinClausePartWhereKey = head(keys(joinClausePartWhere)); | ||
const keysAreEqualBetweenJoinWhereAndMainWhere = joinClausePart.key === whereAndClauseDetailKey && joinClausePart.key === joinClausePartWhereKey; | ||
if (keysAreEqualBetweenJoinWhereAndMainWhere && keys(joinClausePartWhere).length === 1) { | ||
const joinPartDetails = joinClausePartWhere[joinClausePartWhereKey]; | ||
const keyConceptDescriptor = conceptsLookup.get(joinClausePart.key); | ||
const containsInOrNinClause = !!joinPartDetails.$in || !!joinPartDetails.$nin; | ||
const isEntitySetOrDomain = keyConceptDescriptor.concept_type === 'entity_set' || | ||
keyConceptDescriptor.concept_type === 'entity_domain'; | ||
if (keys(joinPartDetails).length === 1 && containsInOrNinClause && isEntitySetOrDomain) { | ||
return interfaces_1.QueryFeature.ConjunctionPartFromWhereClauseCorrespondsToJoin; | ||
try { | ||
for (var _b = tslib_1.__values(query.where.$and), _c = _b.next(); !_c.done; _c = _b.next()) { | ||
var whereAndClauseDetail = _c.value; | ||
var whereAndClauseDetailKeys = keys(whereAndClauseDetail); | ||
if (whereAndClauseDetailKeys.length === 1) { | ||
var whereAndClauseDetailKey = head(whereAndClauseDetailKeys); | ||
var whereAndClauseDetailValue = whereAndClauseDetail[whereAndClauseDetailKey]; | ||
if (query.join && query.join[whereAndClauseDetailValue]) { | ||
var joinClausePart = query.join[whereAndClauseDetailValue]; | ||
var joinClausePartWhere = joinClausePart.where; | ||
var joinClausePartWhereKey = head(keys(joinClausePartWhere)); | ||
var keysAreEqualBetweenJoinWhereAndMainWhere = joinClausePart.key === whereAndClauseDetailKey && joinClausePart.key === joinClausePartWhereKey; | ||
if (keysAreEqualBetweenJoinWhereAndMainWhere && keys(joinClausePartWhere).length === 1) { | ||
var joinPartDetails = joinClausePartWhere[joinClausePartWhereKey]; | ||
var keyConceptDescriptor = conceptsLookup.get(joinClausePart.key); | ||
var containsInOrNinClause = !!joinPartDetails.$in || !!joinPartDetails.$nin; | ||
var isEntitySetOrDomain = keyConceptDescriptor.concept_type === 'entity_set' || | ||
keyConceptDescriptor.concept_type === 'entity_domain'; | ||
if (keys(joinPartDetails).length === 1 && containsInOrNinClause && isEntitySetOrDomain) { | ||
return interfaces_1.QueryFeature.ConjunctionPartFromWhereClauseCorrespondsToJoin; | ||
} | ||
} | ||
@@ -47,2 +52,9 @@ } | ||
} | ||
catch (e_1_1) { e_1 = { error: e_1_1 }; } | ||
finally { | ||
try { | ||
if (_c && !_c.done && (_a = _b.return)) _a.call(_b); | ||
} | ||
finally { if (e_1) throw e_1.error; } | ||
} | ||
return null; | ||
@@ -49,0 +61,0 @@ } |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const get = require("lodash.get"); | ||
const includes = require("lodash.includes"); | ||
var tslib_1 = require("tslib"); | ||
var get = require("lodash.get"); | ||
var includes = require("lodash.includes"); | ||
exports.SCHEMAS = new Set(['concepts.schema', 'entities.schema', 'datapoints.schema', '*.schema']); | ||
@@ -25,5 +26,5 @@ exports.DATAPOINTS = 'datapoints'; | ||
]); | ||
exports.AVAILABLE_FROM_CLAUSE_VALUES = new Set([ | ||
exports.CONCEPTS, exports.ENTITIES, exports.DATAPOINTS, ...exports.SCHEMAS | ||
]); | ||
exports.AVAILABLE_FROM_CLAUSE_VALUES = new Set(tslib_1.__spread([ | ||
exports.CONCEPTS, exports.ENTITIES, exports.DATAPOINTS | ||
], exports.SCHEMAS)); | ||
exports.AVAILABLE_ORDER_BY_CLAUSE_VALUES = new Set([ | ||
@@ -36,3 +37,3 @@ 'asc', 'desc', 1, -1 | ||
function isSchemaQuery(query) { | ||
const fromClause = get(query, 'from'); | ||
var fromClause = get(query, 'from'); | ||
return exports.SCHEMAS.has(fromClause); | ||
@@ -42,3 +43,3 @@ } | ||
function isDatapointsQuery(query) { | ||
const fromClause = get(query, 'from'); | ||
var fromClause = get(query, 'from'); | ||
return fromClause === exports.DATAPOINTS; | ||
@@ -48,3 +49,3 @@ } | ||
function isEntitiesQuery(query) { | ||
const fromClause = get(query, 'from'); | ||
var fromClause = get(query, 'from'); | ||
return fromClause === exports.ENTITIES; | ||
@@ -54,3 +55,3 @@ } | ||
function isConceptsQuery(query) { | ||
const fromClause = get(query, 'from'); | ||
var fromClause = get(query, 'from'); | ||
return fromClause === exports.CONCEPTS; | ||
@@ -57,0 +58,0 @@ } |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const tslib_1 = require("tslib"); | ||
var tslib_1 = require("tslib"); | ||
tslib_1.__exportStar(require("./helper.service"), exports); | ||
@@ -5,0 +5,0 @@ tslib_1.__exportStar(require("./definition.service"), exports); |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const isEmpty = require("lodash.isempty"); | ||
const isNil = require("lodash.isnil"); | ||
const isObject = require("lodash.isobject"); | ||
const isArray = require("lodash.isarray"); | ||
const size = require("lodash.size"); | ||
const cloneDeep = require("lodash.clonedeep"); | ||
const values = require("lodash.values"); | ||
const keys = require("lodash.keys"); | ||
const map = require("lodash.map"); | ||
const flatMap = require("lodash.flatmap"); | ||
const first = require("lodash.first"); | ||
const filter = require("lodash.filter"); | ||
const startsWith = require("lodash.startswith"); | ||
const get = require("lodash.get"); | ||
const has = require("lodash.has"); | ||
const every = require("lodash.every"); | ||
const compact = require("lodash.compact"); | ||
const isString = require("lodash.isstring"); | ||
const includes = require("lodash.includes"); | ||
const uniq = require("lodash.uniq"); | ||
const helper_service_1 = require("./helper.service"); | ||
const util_1 = require("util"); | ||
function validateQueryStructure(query, options = {}) { | ||
return new Promise((resolve, reject) => { | ||
const validationResult = [ | ||
...validateDatasetStructure(query, options), | ||
...validateFromStructure(query, options), | ||
...validateSelectStructure(query, options), | ||
...validateWhereStructure(query, options), | ||
...validateLanguageStructure(query, options), | ||
...validateJoinStructure(query, options), | ||
...validateOrderByStructure(query, options), | ||
]; | ||
const isQueryValid = isEmpty(validationResult); | ||
var tslib_1 = require("tslib"); | ||
var isEmpty = require("lodash.isempty"); | ||
var isNil = require("lodash.isnil"); | ||
var isObject = require("lodash.isobject"); | ||
var isArray = require("lodash.isarray"); | ||
var size = require("lodash.size"); | ||
var cloneDeep = require("lodash.clonedeep"); | ||
var values = require("lodash.values"); | ||
var keys = require("lodash.keys"); | ||
var map = require("lodash.map"); | ||
var flatMap = require("lodash.flatmap"); | ||
var first = require("lodash.first"); | ||
var filter = require("lodash.filter"); | ||
var startsWith = require("lodash.startswith"); | ||
var get = require("lodash.get"); | ||
var has = require("lodash.has"); | ||
var every = require("lodash.every"); | ||
var compact = require("lodash.compact"); | ||
var isString = require("lodash.isstring"); | ||
var includes = require("lodash.includes"); | ||
var uniq = require("lodash.uniq"); | ||
var helper_service_1 = require("./helper.service"); | ||
var util_1 = require("util"); | ||
function validateQueryStructure(query, options) { | ||
if (options === void 0) { options = {}; } | ||
return new Promise(function (resolve, reject) { | ||
var validationResult = tslib_1.__spread(validateDatasetStructure(query, options), validateFromStructure(query, options), validateSelectStructure(query, options), validateWhereStructure(query, options), validateLanguageStructure(query, options), validateJoinStructure(query, options), validateOrderByStructure(query, options)); | ||
var isQueryValid = isEmpty(validationResult); | ||
if (!isQueryValid) { | ||
return reject(`Too many query structure errors: \n* ${validationResult.join('\n* ')}`); | ||
return reject("Too many query structure errors: \n* " + validationResult.join('\n* ')); | ||
} | ||
@@ -49,14 +43,14 @@ return resolve(); | ||
function validateDatasetStructure(query, options) { | ||
const errorMessages = []; | ||
const datasetClause = get(query, 'dataset'); | ||
const branchClause = get(query, 'branch'); | ||
const commitClause = get(query, 'commit'); | ||
var errorMessages = []; | ||
var datasetClause = get(query, 'dataset'); | ||
var branchClause = get(query, 'branch'); | ||
var commitClause = get(query, 'commit'); | ||
if (!isNil(datasetClause) && !isString(datasetClause)) { | ||
errorMessages.push(`'dataset' clause must be string only`); | ||
errorMessages.push("'dataset' clause must be string only"); | ||
} | ||
if (!isNil(branchClause) && !isString(branchClause)) { | ||
errorMessages.push(`'branch' clause must be string only`); | ||
errorMessages.push("'branch' clause must be string only"); | ||
} | ||
if (!isNil(commitClause) && !isString(commitClause)) { | ||
errorMessages.push(`'commit' clause must be string only`); | ||
errorMessages.push("'commit' clause must be string only"); | ||
} | ||
@@ -66,13 +60,13 @@ return errorMessages; | ||
function validateFromStructure(query, options) { | ||
const errorMessages = []; | ||
const clause = get(query, 'from', null); | ||
var errorMessages = []; | ||
var clause = get(query, 'from', null); | ||
if (isNil(clause)) { | ||
errorMessages.push(`'from' clause couldn't be empty`); | ||
errorMessages.push("'from' clause couldn't be empty"); | ||
} | ||
if (!isString(clause)) { | ||
errorMessages.push(`'from' clause must be string only`); | ||
errorMessages.push("'from' clause must be string only"); | ||
} | ||
if (!helper_service_1.AVAILABLE_FROM_CLAUSE_VALUES.has(clause)) { | ||
const listAvaliableValues = [...helper_service_1.AVAILABLE_FROM_CLAUSE_VALUES]; | ||
errorMessages.push(`'from' clause must be one of the list: ${listAvaliableValues.join(', ')}`); | ||
var listAvaliableValues = tslib_1.__spread(helper_service_1.AVAILABLE_FROM_CLAUSE_VALUES); | ||
errorMessages.push("'from' clause must be one of the list: " + listAvaliableValues.join(', ')); | ||
} | ||
@@ -82,7 +76,7 @@ return errorMessages; | ||
function validateSelectStructure(query, options) { | ||
const errorMessages = []; | ||
const selectClause = get(query, 'select', null); | ||
const fromClause = get(query, 'from', null); | ||
const key = get(selectClause, 'key'); | ||
const value = get(selectClause, 'value'); | ||
var errorMessages = []; | ||
var selectClause = get(query, 'select', null); | ||
var fromClause = get(query, 'from', null); | ||
var key = get(selectClause, 'key'); | ||
var value = get(selectClause, 'value'); | ||
switch (true) { | ||
@@ -108,6 +102,6 @@ case (helper_service_1.isSchemaQuery(query)): | ||
function validateWhereStructure(query, options) { | ||
const errorMessages = []; | ||
const joinClause = get(query, 'join', null); | ||
const whereClause = get(query, 'where', null); | ||
const whereOperators = getWhereOperators(whereClause); | ||
var errorMessages = []; | ||
var joinClause = get(query, 'join', null); | ||
var whereClause = get(query, 'where', null); | ||
var whereOperators = getWhereOperators(whereClause); | ||
errorMessages.push(checkIfWhereHasInvalidStructure(whereClause, getJoinIDPathIfExists(options)), checkIfWhereHasUnknownOperators(joinClause, whereOperators, getJoinIDPathIfExists(options))); | ||
@@ -117,4 +111,4 @@ return compact(errorMessages); | ||
function validateLanguageStructure(query, options) { | ||
const errorMessages = []; | ||
const languageClause = get(query, 'language', null); | ||
var errorMessages = []; | ||
var languageClause = get(query, 'language', null); | ||
switch (true) { | ||
@@ -134,4 +128,4 @@ case (helper_service_1.isSchemaQuery(query)): | ||
function validateJoinStructure(query, options) { | ||
const errorMessages = []; | ||
const joinClause = get(query, 'join', null); | ||
var errorMessages = []; | ||
var joinClause = get(query, 'join', null); | ||
switch (true) { | ||
@@ -145,3 +139,3 @@ case (helper_service_1.isSchemaQuery(query)): | ||
default: | ||
errorMessages.push(checkIfJoinHasInvalidStructure(joinClause), ...map(joinClause, (item, joinID) => checkIfJoinKeyHasInvalidStructure(item, getJoinIDPathIfExists({ joinID })))); | ||
errorMessages.push.apply(errorMessages, tslib_1.__spread([checkIfJoinHasInvalidStructure(joinClause)], map(joinClause, function (item, joinID) { return checkIfJoinKeyHasInvalidStructure(item, getJoinIDPathIfExists({ joinID: joinID })); }))); | ||
break; | ||
@@ -152,4 +146,4 @@ } | ||
function validateOrderByStructure(query, options) { | ||
const errorMessages = []; | ||
const orderByClause = get(query, 'order_by', null); | ||
var errorMessages = []; | ||
var orderByClause = get(query, 'order_by', null); | ||
errorMessages.push(checkIfOrderByHasInvalidStructure(orderByClause)); | ||
@@ -159,16 +153,22 @@ return compact(errorMessages); | ||
function validateSubqueries(query, options) { | ||
return flatMap(query.join, async (join, joinID) => { | ||
return await validateQueryStructure({ | ||
select: { key: [join.key] }, | ||
where: join.where, | ||
from: query.from === 'entities' ? 'concepts' : 'entities', | ||
dataset: query.dataset, | ||
branch: query.branch, | ||
commit: query.commit | ||
}, Object.assign({ joinID }, cloneDeep(options))); | ||
}); | ||
var _this = this; | ||
return flatMap(query.join, function (join, joinID) { return tslib_1.__awaiter(_this, void 0, void 0, function () { | ||
return tslib_1.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4, validateQueryStructure({ | ||
select: { key: [join.key] }, | ||
where: join.where, | ||
from: query.from === 'entities' ? 'concepts' : 'entities', | ||
dataset: query.dataset, | ||
branch: query.branch, | ||
commit: query.commit | ||
}, Object.assign({ joinID: joinID }, cloneDeep(options)))]; | ||
case 1: return [2, _a.sent()]; | ||
} | ||
}); | ||
}); }); | ||
} | ||
function checkIfSelectIsEmpty(selectClause) { | ||
if (isNil(selectClause)) { | ||
return `'select' clause couldn't be empty`; | ||
return "'select' clause couldn't be empty"; | ||
} | ||
@@ -178,3 +178,3 @@ } | ||
if (!isObject(selectClause) || !isArray(key) || !isArray(value)) { | ||
return `'select' clause must have next structure: { key: [...], value: [...] }`; | ||
return "'select' clause must have next structure: { key: [...], value: [...] }"; | ||
} | ||
@@ -184,3 +184,3 @@ } | ||
if (!isNil(joinClause) && !isStrictObject(joinClause)) { | ||
return `'join' clause must be object only`; | ||
return "'join' clause must be object only"; | ||
} | ||
@@ -190,3 +190,3 @@ } | ||
if (!isNil(languageClause) && !isString(languageClause)) { | ||
return `'language' clause must be string only`; | ||
return "'language' clause must be string only"; | ||
} | ||
@@ -196,3 +196,3 @@ } | ||
if (!isNil(joinClause.key) && !isString(joinClause.key)) { | ||
return `'${joinPath}key' clause must be string only`; | ||
return "'" + joinPath + "key' clause must be string only"; | ||
} | ||
@@ -202,10 +202,10 @@ } | ||
if (!isNil(whereClause) && !isStrictObject(whereClause)) { | ||
return `'${joinPath}where' clause must be object only`; | ||
return "'" + joinPath + "where' clause must be object only"; | ||
} | ||
} | ||
function checkIfWhereHasUnknownOperators(joinClause, operators, joinPath) { | ||
const notAllowedOperators = filter(operators, (operator) => !isAllowedOperator(joinClause, operator)).map((operator) => operator.name); | ||
const allowedOperatorsByDataset = [...helper_service_1.AVAILABLE_QUERY_OPERATORS.values(), ...keys(joinClause)]; | ||
var notAllowedOperators = filter(operators, function (operator) { return !isAllowedOperator(joinClause, operator); }).map(function (operator) { return operator.name; }); | ||
var allowedOperatorsByDataset = tslib_1.__spread(helper_service_1.AVAILABLE_QUERY_OPERATORS.values(), keys(joinClause)); | ||
if (!isEmpty(notAllowedOperators)) { | ||
return `'${joinPath}where' clause has unknown operator(s) '${notAllowedOperators.join(', ')}', replace it with allowed operators: ${allowedOperatorsByDataset.join(', ')}`; | ||
return "'" + joinPath + "where' clause has unknown operator(s) '" + notAllowedOperators.join(', ') + "', replace it with allowed operators: " + allowedOperatorsByDataset.join(', '); | ||
} | ||
@@ -215,3 +215,3 @@ } | ||
if (!isNil(orderByClause) && !isString(orderByClause) && !isArrayOfStrings(orderByClause) && !isArrayOfSpecialItems(orderByClause, isOrderBySubclause)) { | ||
return `'order_by' clause must be string or array of strings || objects only`; | ||
return "'order_by' clause must be string or array of strings || objects only"; | ||
} | ||
@@ -241,10 +241,10 @@ } | ||
function getDuplicates(array) { | ||
return filter(array, (value, index, iteratee) => includes(iteratee, value, index + 1)); | ||
return filter(array, function (value, index, iteratee) { return includes(iteratee, value, index + 1); }); | ||
} | ||
function getJoinIDPathIfExists(options) { | ||
return get(options, 'joinID', false) ? `join.${options.joinID}.` : ''; | ||
return get(options, 'joinID', false) ? "join." + options.joinID + "." : ''; | ||
} | ||
function getWhereOperators(whereClause) { | ||
const operators = []; | ||
for (const field in whereClause) { | ||
var operators = []; | ||
for (var field in whereClause) { | ||
if (startsWith(field, '$')) { | ||
@@ -259,3 +259,3 @@ operators.push({ name: field, isLeaf: false }); | ||
else { | ||
operators.push(...getWhereOperators(whereClause[field])); | ||
operators.push.apply(operators, tslib_1.__spread(getWhereOperators(whereClause[field]))); | ||
} | ||
@@ -267,9 +267,9 @@ } | ||
if (size(key) < 2) { | ||
return `'select.key' clause for '${fromClause}' queries must have at least 2 items`; | ||
return "'select.key' clause for '" + fromClause + "' queries must have at least 2 items"; | ||
} | ||
} | ||
function checkIfDatapointsSelectKeyHasDuplicates(fromClause, key) { | ||
const duplicates = getDuplicates(key); | ||
var duplicates = getDuplicates(key); | ||
if (size(duplicates) > 0) { | ||
return `'select.key' clause for '${fromClause}' queries contains duplicates: ${uniq(duplicates).join(',')}`; | ||
return "'select.key' clause for '" + fromClause + "' queries contains duplicates: " + uniq(duplicates).join(','); | ||
} | ||
@@ -279,3 +279,3 @@ } | ||
if (size(value) < 1) { | ||
return `'select.value' clause for '${fromClause}' queries must have at least 1 item`; | ||
return "'select.value' clause for '" + fromClause + "' queries must have at least 1 item"; | ||
} | ||
@@ -285,3 +285,3 @@ } | ||
if (!isArray(key) || size(key) !== 2) { | ||
return `'select.key' clause for '${fromClause}' queries must have exactly 2 items: 'key', 'value'`; | ||
return "'select.key' clause for '" + fromClause + "' queries must have exactly 2 items: 'key', 'value'"; | ||
} | ||
@@ -291,3 +291,3 @@ } | ||
if (!isArray(value) && !isNil(value)) { | ||
return `'select.value' clause for '${fromClause}' queries should be array of strings or empty`; | ||
return "'select.value' clause for '" + fromClause + "' queries should be array of strings or empty"; | ||
} | ||
@@ -297,3 +297,3 @@ } | ||
if (has(query, 'join')) { | ||
return `'join' clause for '${query.from}' queries shouldn't be present in query`; | ||
return "'join' clause for '" + query.from + "' queries shouldn't be present in query"; | ||
} | ||
@@ -303,3 +303,3 @@ } | ||
if (has(query, 'language')) { | ||
return `'language' clause for '*.schema' queries shouldn't be present in query`; | ||
return "'language' clause for '*.schema' queries shouldn't be present in query"; | ||
} | ||
@@ -309,3 +309,3 @@ } | ||
if (!isObject(selectClause) || !isArray(key)) { | ||
return `'select' clause must have next structure: { key: [...], value: [...] }`; | ||
return "'select' clause must have next structure: { key: [...], value: [...] }"; | ||
} | ||
@@ -315,5 +315,5 @@ } | ||
if (!isArray(key) || size(key) !== 1) { | ||
return `'select.key' clause for '${fromClause}' queries must have only 1 item`; | ||
return "'select.key' clause for '" + fromClause + "' queries must have only 1 item"; | ||
} | ||
} | ||
//# sourceMappingURL=structure.service.js.map |
{ | ||
"name": "ddf-query-validator", | ||
"version": "1.3.0", | ||
"version": "1.3.1", | ||
"description": "DDF query validator", | ||
@@ -5,0 +5,0 @@ "main": "lib/index.js", |
{ | ||
"compilerOptions": { | ||
"declaration": true, | ||
"target": "es2017", | ||
"target": "es5", | ||
"module": "commonjs", | ||
@@ -24,3 +24,4 @@ "noImplicitAny": false, | ||
"dom" | ||
] | ||
], | ||
"downlevelIteration": true | ||
}, | ||
@@ -27,0 +28,0 @@ "include": [ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
174393
2961