UNPKG

api-core

Version:

Model-based dynamic multi-level APIs for any provider, plus multiple consumption channels

700 lines 35.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ApiQueryBuilder = exports.ExtendContextLiveQueryStep = exports.ExtendContextQueryStep = exports.ProvideIdQueryStep = exports.SetBodyQueryStep = exports.SetResponseQueryStep = exports.RelateBackwardsChangeQueryStep = exports.RelateChangeQueryStep = exports.RelateBackwardsQueryStep = exports.RelateQueryStep = exports.CallMethodQueryStep = exports.QueryEdgeQueryStep = exports.EmbedQueryQueryStep = void 0; const ApiQuery_1 = require("./ApiQuery"); const ApiEdgeQuery_1 = require("../edge/ApiEdgeQuery"); const ApiEdgeQueryContext_1 = require("../edge/ApiEdgeQueryContext"); const ApiEdgeError_1 = require("./ApiEdgeError"); const ApiEdgeQueryFilter_1 = require("../edge/ApiEdgeQueryFilter"); const ApiRequest_1 = require("../request/ApiRequest"); const ApiEdgeQueryResponse_1 = require("../edge/ApiEdgeQueryResponse"); const ApiEdgeQueryType_1 = require("../edge/ApiEdgeQueryType"); const OneToOneRelation_1 = require("../relations/OneToOneRelation"); const Api_1 = require("../Api"); const ApiEdgeMethod_1 = require("../edge/ApiEdgeMethod"); const ApiEdgeAction_1 = require("../edge/ApiEdgeAction"); const ApiAction_1 = require("./ApiAction"); const OneToManyRelation_1 = require("../relations/OneToManyRelation"); const parse = require('obj-parse'); const debug = require('debug')('api-core'); class EmbedQueryQueryStep { constructor(query, segment, request) { this.execute = (scope) => { return new Promise((resolve, reject) => { debug(`[${scope.query.id}]`, this.inspect()); if (scope.response) { const target = scope.response.data; if (Array.isArray(target)) { const targetIndex = {}, targetArrayIndex = {}, ids = []; for (let entry of target) { const id = entry[this.sourceField]; if (id) { if (Array.isArray(id)) { let index = 0; for (let _id of id) { if (targetArrayIndex[_id]) targetArrayIndex[_id].push({ entry, index }); else targetArrayIndex[_id] = [{ entry, index }]; ids.push(_id); index++; } entry[this.sourceField] = []; } else { if (targetIndex[id]) targetIndex[id].push(entry); else targetIndex[id] = [entry]; ids.push(id); if (this.forceArray) entry[this.targetField] = []; } } } this.request.context.filters = [ new ApiEdgeQueryFilter_1.ApiEdgeQueryFilter(this.idField, ApiEdgeQueryFilter_1.ApiEdgeQueryFilterType.In, ids) ]; this.query.execute(scope.identity).then((response) => { if (response.data && response.data.length) { for (let entry of response.data) { let ids = entry[this.idField]; if (!Array.isArray(ids)) { ids = [ids]; } for (let id of ids) { if (targetIndex[id]) { for (let subEntry of targetIndex[id]) { if (this.forceArray) subEntry[this.targetField].push(entry); else subEntry[this.targetField] = entry; } } if (targetArrayIndex[id]) { for (let { entry: subEntry, index } of targetArrayIndex[id]) { subEntry[this.targetField][index] = entry; } } } } } resolve(scope); }).catch(reject); } else { const sourceId = target[this.sourceField]; if (!sourceId) { resolve(scope); return; } if (Array.isArray(sourceId)) { this.request.context.filters = [ new ApiEdgeQueryFilter_1.ApiEdgeQueryFilter(this.idField, ApiEdgeQueryFilter_1.ApiEdgeQueryFilterType.In, sourceId) ]; } else if (this.forceArray) { this.request.context.filters = [ new ApiEdgeQueryFilter_1.ApiEdgeQueryFilter(this.idField, ApiEdgeQueryFilter_1.ApiEdgeQueryFilterType.Equals, sourceId) ]; } else { this.segment.id = sourceId; } this.query.execute(scope.identity).then((response) => { if (Array.isArray(sourceId)) { const unordered_data = response.data; response.data = []; for (const id of sourceId) { const item = unordered_data.find((item) => { return item.id.toString() == id.toString(); }); if (item) response.data.push(item); else console.warn("WARNING: can\'t find in embed results this id: " + id); } } target[this.targetField] = response.data; resolve(scope); }).catch(e => { console.warn(e); resolve(scope); }); } } else resolve(scope); }); }; this.inspect = () => `EMBED QUERY /${this.sourceField} -> ${this.targetField}`; this.query = query; this.query.request = this.request = request; this.segment = segment; if (!this.segment.relation) throw new Error('Invalid relation provided.'); this.sourceField = this.segment.relation.relationId; this.targetField = this.segment.relation.name; this.idField = this.segment.relation.relatedId; this.forceArray = this.segment.relation instanceof OneToManyRelation_1.OneToManyRelation; this.isMultiMulti = this.segment.relation.hasPair; } } exports.EmbedQueryQueryStep = EmbedQueryQueryStep; class QueryEdgeQueryStep { constructor(query) { this.execute = (scope) => { return new Promise((resolve, reject) => { debug(`[${scope.query.id}]`, this.inspect()); if (this.query.type !== ApiEdgeQueryType_1.ApiEdgeQueryType.Get && this.query.type !== ApiEdgeQueryType_1.ApiEdgeQueryType.List) { this.query.body = scope.body; } this.query.context = scope.context; this.query.context.populatedRelations = []; this.query.context.identity = scope.identity; this.query.execute().then((response) => { scope.context = new ApiEdgeQueryContext_1.ApiEdgeQueryContext(); scope.response = response; resolve(scope); }).catch(reject); }); }; this.inspect = () => `QUERY /${this.query.edge.pluralName}`; this.query = query; } } exports.QueryEdgeQueryStep = QueryEdgeQueryStep; class CallMethodQueryStep { constructor(method, edge) { this.execute = (scope) => { return new Promise((resolve, reject) => { debug(`[${scope.query.id}]`, this.inspect()); scope.context.method = this.method.name; this.method.execute(scope) .then((response) => { scope.response = response; resolve(scope); }).catch((e) => { debug(`failed to execute ${this.method.name} method`, e); reject(e); }); }); }; this.inspect = () => `call{${this.method.name}}`; this.method = method; this.edge = edge; } } exports.CallMethodQueryStep = CallMethodQueryStep; class RelateQueryStep { constructor(relation) { this.execute = (scope) => { return new Promise((resolve, reject) => { debug(`[${scope.query.id}]`, this.inspect()); if (!scope.response) return reject(new ApiEdgeError_1.ApiEdgeError(404, "Missing Related Entry")); scope.context.filter(this.relation.relationId, ApiEdgeQueryFilter_1.ApiEdgeQueryFilterType.Equals, scope.response.data[this.relation.relatedId]); resolve(scope); }); }; this.inspect = () => `RELATE ${this.relation.relationId} = ${this.relation.relatedId}`; this.relation = relation; } } exports.RelateQueryStep = RelateQueryStep; class RelateBackwardsQueryStep { constructor(relation) { this.execute = (scope) => { return new Promise((resolve, reject) => { debug(`[${scope.query.id}]`, this.inspect()); if (!scope.response) return reject(new ApiEdgeError_1.ApiEdgeError(404, "Missing Related Entry")); scope.context.filter(this.relation.relatedId, ApiEdgeQueryFilter_1.ApiEdgeQueryFilterType.Equals, scope.response.data[this.relation.relationId]); resolve(scope); }); }; this.inspect = () => `RELATE ${this.relation.relatedId} = ${this.relation.relationId}`; this.relation = relation; } } exports.RelateBackwardsQueryStep = RelateBackwardsQueryStep; class RelateChangeQueryStep { constructor(relation) { this.execute = (scope) => { return new Promise((resolve, reject) => { debug(`[${scope.query.id}]`, this.inspect()); if (!scope.body) return reject(new ApiEdgeError_1.ApiEdgeError(404, "Missing Body")); if (!scope.response) return reject(new ApiEdgeError_1.ApiEdgeError(404, "Missing Related Entry")); parse(this.relation.relationId).assign(scope.body, scope.response.data[this.relation.relatedId].toString()); resolve(scope); }); }; this.inspect = () => `RELATE CHANGE ${this.relation.relationId}`; this.relation = relation; } } exports.RelateChangeQueryStep = RelateChangeQueryStep; class RelateBackwardsChangeQueryStep { constructor(relation) { this.execute = (scope) => { return new Promise((resolve, reject) => { debug(`[${scope.query.id}]`, this.inspect()); if (!scope.body) return reject(new ApiEdgeError_1.ApiEdgeError(404, "Missing Body")); if (!scope.response) return reject(new ApiEdgeError_1.ApiEdgeError(404, "Missing Related Entry")); parse(this.relation.relatedId).assign(scope.body, scope.response.data[this.relation.relationId].toString()); resolve(scope); }); }; this.inspect = () => `RELATE CHANGE BACKWARD ${this.relation.relatedId}`; this.relation = relation; } } exports.RelateBackwardsChangeQueryStep = RelateBackwardsChangeQueryStep; class SetResponseQueryStep { constructor(response) { this.execute = (scope) => { return new Promise(resolve => { debug(`[${scope.query.id}]`, this.inspect()); scope.response = this.response; scope.context = new ApiEdgeQueryContext_1.ApiEdgeQueryContext(); resolve(scope); }); }; this.inspect = () => `SET RESPONSE`; this.response = response; } } exports.SetResponseQueryStep = SetResponseQueryStep; class SetBodyQueryStep { constructor(body, stream = null) { this.execute = (scope) => { return new Promise(resolve => { debug(`[${scope.query.id}]`, this.inspect()); scope.body = this.body; scope.stream = this.stream; resolve(scope); }); }; this.inspect = () => `SET BODY`; this.body = body; this.stream = stream; } } exports.SetBodyQueryStep = SetBodyQueryStep; class ProvideIdQueryStep { constructor(fieldName = Api_1.Api.defaultIdField) { this.execute = (scope) => { return new Promise((resolve, reject) => { debug(`[${scope.query.id}]`, this.inspect()); if (!scope.response) return reject(new ApiEdgeError_1.ApiEdgeError(404, "Missing Entry")); scope.context.id = scope.response.data[this.fieldName]; resolve(scope); }); }; this.inspect = () => `PROVIDE ID: ${this.fieldName}`; this.fieldName = fieldName; } } exports.ProvideIdQueryStep = ProvideIdQueryStep; class ExtendContextQueryStep { constructor(context) { this.execute = (scope) => { return new Promise(resolve => { debug(`[${scope.query.id}]`, this.inspect()); scope.context.id = this.context.id || scope.context.id; if (this.context.pagination) { scope.context.pagination = this.context.pagination; } this.context.fields.forEach(f => scope.context.fields.push(f)); this.context.populatedRelations.forEach(f => scope.context.populatedRelations.push(f)); this.context.filters.forEach(f => scope.context.filters.push(f)); this.context.sortBy.forEach(f => scope.context.sortBy.push(f)); resolve(scope); }); }; this.inspect = () => { if (this.context.id) { return `EXTEND CONTEXT (id=${this.context.id})`; } else { return `APPLY PARAMETERS`; } }; this.context = context; } } exports.ExtendContextQueryStep = ExtendContextQueryStep; class ExtendContextLiveQueryStep { constructor(func) { this.execute = (scope) => { return new Promise(resolve => { debug(`[${scope.query.id}]`, this.inspect()); this.apply(scope.context); resolve(scope); }); }; this.inspect = () => { return `EXTEND CONTEXT LIVE`; }; this.apply = func; } } exports.ExtendContextLiveQueryStep = ExtendContextLiveQueryStep; class ApiQueryBuilder { constructor(api) { this.buildReadQuery = (request) => { let query = new ApiQuery_1.ApiQuery(); let segments = request.path.segments, lastSegment = segments[segments.length - 1]; this.buildEmbedSteps(query, request, lastSegment); let readMode = true; let baseQuery; if (lastSegment instanceof ApiRequest_1.EdgePathSegment) { baseQuery = new ApiEdgeQuery_1.ApiEdgeQuery(lastSegment.edge, ApiEdgeQueryType_1.ApiEdgeQueryType.List); this.addQueryStep(query, new QueryEdgeQueryStep(baseQuery), null, true); } else if (lastSegment instanceof ApiRequest_1.RelatedFieldPathSegment) { baseQuery = new ApiEdgeQuery_1.ApiEdgeQuery(lastSegment.relation.to, ApiEdgeQueryType_1.ApiEdgeQueryType.Get); this.addQueryStep(query, new QueryEdgeQueryStep(baseQuery), lastSegment.relation, true); } else if (lastSegment instanceof ApiRequest_1.MethodPathSegment) { this.addMethodCallStep(request, query, lastSegment.method, lastSegment.edge, true); if (lastSegment.method.scope === ApiEdgeMethod_1.ApiEdgeMethodScope.Entry) { query.unshift(new ProvideIdQueryStep(lastSegment.edge.idField)); } readMode = lastSegment.method.requiresData; } else { baseQuery = new ApiEdgeQuery_1.ApiEdgeQuery(lastSegment.edge, ApiEdgeQueryType_1.ApiEdgeQueryType.Get); this.addQueryStep(query, new QueryEdgeQueryStep(baseQuery), null, true); } query.unshift(new ExtendContextQueryStep(request.context)); if (lastSegment instanceof ApiRequest_1.EntryPathSegment) { const _segment = lastSegment; query.unshift(new ExtendContextLiveQueryStep(context => context.id = _segment.id)); } else if (lastSegment instanceof ApiRequest_1.RelatedFieldPathSegment) { if (lastSegment.relation.relatedId !== lastSegment.relation.to.idField) { query.unshift(new RelateBackwardsQueryStep(lastSegment.relation)); } else { query.unshift(new ProvideIdQueryStep(lastSegment.relation.relationId)); } } else { } for (let i = segments.length - 2; i >= 0; i--) { let currentSegment = segments[i]; let relation = segments[i + 1].relation; let edge = segments[i + 1].edge; if (relation && !(relation instanceof OneToOneRelation_1.OneToOneRelation)) { if (edge === relation.to) { query.unshift(new RelateBackwardsQueryStep(relation)); } else { query.unshift(new RelateQueryStep(relation)); } } if (readMode) { readMode = this.buildReadStep(query, currentSegment); } else { readMode = this.buildCheckStep(query, currentSegment); } } this.api.actions .filter((action) => action.triggerKind == ApiAction_1.ApiActionTriggerKind.OnInput) .forEach((action) => query.unshift(action)); return query; }; this.buildChangeQuery = (request) => { let query = new ApiQuery_1.ApiQuery(); let segments = request.path.segments, lastSegment = segments[segments.length - 1], readMode = true; this.buildEmbedSteps(query, request, lastSegment); let baseQuery; if (lastSegment instanceof ApiRequest_1.RelatedFieldPathSegment) { if (request.type === ApiRequest_1.ApiRequestType.Update) { baseQuery = new ApiEdgeQuery_1.ApiEdgeQuery(lastSegment.edge, ApiEdgeQueryType_1.ApiEdgeQueryType.Patch); request.body = { [lastSegment.relation.relationId]: request.body.id || request.body._id }; this.addQueryStep(query, new QueryEdgeQueryStep(baseQuery), null, true); } else if (request.type === ApiRequest_1.ApiRequestType.Patch) { baseQuery = new ApiEdgeQuery_1.ApiEdgeQuery(lastSegment.relation.to, ApiEdgeQueryType_1.ApiEdgeQueryType.Patch); this.addQueryStep(query, new QueryEdgeQueryStep(baseQuery), null, true); } else { throw new ApiEdgeError_1.ApiEdgeError(400, "Invalid Delete Query"); } } else if (lastSegment instanceof ApiRequest_1.MethodPathSegment) { this.addMethodCallStep(request, query, lastSegment.method, lastSegment.edge, true); if (lastSegment.method.scope === ApiEdgeMethod_1.ApiEdgeMethodScope.Entry) { query.unshift(new ProvideIdQueryStep(lastSegment.edge.idField)); } readMode = lastSegment.method.requiresData; } else { if (request.type === ApiRequest_1.ApiRequestType.Update) { baseQuery = new ApiEdgeQuery_1.ApiEdgeQuery(lastSegment.edge, ApiEdgeQueryType_1.ApiEdgeQueryType.Update); this.addQueryStep(query, new QueryEdgeQueryStep(baseQuery), null, true); } else if (request.type === ApiRequest_1.ApiRequestType.Patch) { baseQuery = new ApiEdgeQuery_1.ApiEdgeQuery(lastSegment.edge, ApiEdgeQueryType_1.ApiEdgeQueryType.Patch); this.addQueryStep(query, new QueryEdgeQueryStep(baseQuery), null, true); } else { baseQuery = new ApiEdgeQuery_1.ApiEdgeQuery(lastSegment.edge, ApiEdgeQueryType_1.ApiEdgeQueryType.Delete); this.addQueryStep(query, new QueryEdgeQueryStep(baseQuery), null, true); } } query.unshift(new ExtendContextQueryStep(request.context)); if (lastSegment instanceof ApiRequest_1.EntryPathSegment) { const _segment = lastSegment; query.unshift(new ExtendContextLiveQueryStep(context => context.id = _segment.id)); } else if (lastSegment instanceof ApiRequest_1.RelatedFieldPathSegment) { if (request.type === ApiRequest_1.ApiRequestType.Update) { let previousSegment = segments[segments.length - 2]; query.unshift(new ProvideIdQueryStep(previousSegment.edge.idField || Api_1.Api.defaultIdField)); readMode = false; } else { query.unshift(new ProvideIdQueryStep(lastSegment.relation.relationId)); } } else { } for (let i = segments.length - 2; i >= 0; i--) { let currentSegment = segments[i]; let relation = segments[i + 1].relation; let edge = segments[i + 1].edge; if (relation && !(relation instanceof OneToOneRelation_1.OneToOneRelation)) { if (edge === relation.to) { query.unshift(new RelateBackwardsQueryStep(relation)); } else { query.unshift(new RelateQueryStep(relation)); } if (request.type !== ApiRequest_1.ApiRequestType.Delete) { if (edge === relation.to) { query.unshift(new RelateBackwardsChangeQueryStep(relation)); } else { query.unshift(new RelateChangeQueryStep(relation)); } } } if (readMode) { readMode = this.buildReadStep(query, currentSegment); } else { readMode = this.buildCheckStep(query, currentSegment); } } if (request.body || request.stream) query.unshift(new SetBodyQueryStep(request.body, request.stream)); this.api.actions .filter((action) => action.triggerKind == ApiAction_1.ApiActionTriggerKind.OnInput) .forEach((action) => query.unshift(action)); return query; }; this.buildCreateQuery = (request) => { let query = new ApiQuery_1.ApiQuery(); let segments = request.path.segments, lastSegment = segments[segments.length - 1], readMode = true; this.buildEmbedSteps(query, request, lastSegment); if (lastSegment instanceof ApiRequest_1.MethodPathSegment) { this.addMethodCallStep(request, query, lastSegment.method, lastSegment.edge, true); if (lastSegment.method.scope === ApiEdgeMethod_1.ApiEdgeMethodScope.Entry) { query.unshift(new ProvideIdQueryStep(lastSegment.edge.idField)); } readMode = lastSegment.method.requiresData; } else { this.addQueryStep(query, new QueryEdgeQueryStep(new ApiEdgeQuery_1.ApiEdgeQuery(lastSegment.edge, ApiEdgeQueryType_1.ApiEdgeQueryType.Create))); } for (let i = segments.length - 2; i >= 0; i--) { let currentSegment = segments[i]; let relation = segments[i + 1].relation; let edge = segments[i + 1].edge; if (relation && !(relation instanceof OneToOneRelation_1.OneToOneRelation)) { if (edge === relation.to) { query.unshift(new RelateBackwardsChangeQueryStep(relation)); } else { query.unshift(new RelateChangeQueryStep(relation)); } } if (readMode) { readMode = this.buildReadStep(query, currentSegment); } else { readMode = this.buildCheckStep(query, currentSegment); } } query.unshift(new SetBodyQueryStep(request.body, request.stream)); this.api.actions .filter((action) => action.triggerKind == ApiAction_1.ApiActionTriggerKind.OnInput) .forEach((action) => query.unshift(action)); return query; }; this.build = (request) => { switch (request.type) { case ApiRequest_1.ApiRequestType.Read: return this.buildReadQuery(request); case ApiRequest_1.ApiRequestType.Update: case ApiRequest_1.ApiRequestType.Patch: case ApiRequest_1.ApiRequestType.Delete: return this.buildChangeQuery(request); case ApiRequest_1.ApiRequestType.Create: return this.buildCreateQuery(request); default: throw new ApiEdgeError_1.ApiEdgeError(400, "Unsupported Query Type"); } }; this.api = api; } addQueryActions(triggerKind, query, edgeQuery, relation, output = false) { const edge = edgeQuery.edge, queryType = edgeQuery.type, trigger = relation ? ApiEdgeAction_1.ApiEdgeActionTrigger.Relation : (output ? ApiEdgeAction_1.ApiEdgeActionTrigger.OutputQuery : ApiEdgeAction_1.ApiEdgeActionTrigger.SubQuery); let actions; if (relation) { actions = edge.actions.filter((action) => action.triggerKind == triggerKind && (action.targetTypes & queryType) && (action.triggers & trigger) && (!action.triggerNames.length || action.triggerNames.indexOf(relation.name) == -1)); } else { actions = edge.actions.filter((action) => action.triggerKind == triggerKind && (action.targetTypes & queryType) && (action.triggers & trigger)); } actions.forEach((action) => query.unshift(action)); if (output) { const apiTrigger = triggerKind == ApiEdgeAction_1.ApiEdgeActionTriggerKind.BeforeEvent ? ApiAction_1.ApiActionTriggerKind.BeforeOutput : ApiAction_1.ApiActionTriggerKind.AfterOutput; this.api.actions .filter((action) => action.triggerKind == apiTrigger) .forEach((action) => query.unshift(action)); } } addMethodActions(triggerKind, query, method, queryType, edge, output = false) { const trigger = ApiEdgeAction_1.ApiEdgeActionTrigger.Method; let actions = edge.actions.filter((action) => action.triggerKind == triggerKind && (action.targetTypes & queryType) && (action.triggers & trigger) && (!action.triggerNames.length || action.triggerNames.indexOf(method.name) == -1)); actions.forEach((action) => query.unshift(action)); if (output) { const apiTrigger = triggerKind == ApiEdgeAction_1.ApiEdgeActionTriggerKind.BeforeEvent ? ApiAction_1.ApiActionTriggerKind.BeforeOutput : ApiAction_1.ApiActionTriggerKind.AfterOutput; this.api.actions .filter((action) => action.triggerKind == apiTrigger) .forEach((action) => query.unshift(action)); } } addMethodCallStep(request, query, method, edge, output) { if (method.acceptedTypes & request.type) { let queryType = ApiEdgeQueryType_1.ApiEdgeQueryType.Any; if (request.type === ApiRequest_1.ApiRequestType.Create) { queryType = ApiEdgeQueryType_1.ApiEdgeQueryType.Create; } else if (request.type === ApiRequest_1.ApiRequestType.Read) { queryType = ApiEdgeQueryType_1.ApiEdgeQueryType.Read; } else if (request.type === ApiRequest_1.ApiRequestType.Update) { queryType = ApiEdgeQueryType_1.ApiEdgeQueryType.Update; } else if (request.type === ApiRequest_1.ApiRequestType.Patch) { queryType = ApiEdgeQueryType_1.ApiEdgeQueryType.Patch; } else if (request.type === ApiRequest_1.ApiRequestType.Delete) { queryType = ApiEdgeQueryType_1.ApiEdgeQueryType.Delete; } else if (request.type === ApiRequest_1.ApiRequestType.Exists) { queryType = ApiEdgeQueryType_1.ApiEdgeQueryType.Exists; } else if (request.type === ApiRequest_1.ApiRequestType.Change) { queryType = ApiEdgeQueryType_1.ApiEdgeQueryType.Change; } this.addMethodActions(ApiEdgeAction_1.ApiEdgeActionTriggerKind.AfterEvent, query, method, queryType, edge, output); query.unshift(new CallMethodQueryStep(method, edge)); this.addMethodActions(ApiEdgeAction_1.ApiEdgeActionTriggerKind.BeforeEvent, query, method, queryType, edge, output); } else { throw new ApiEdgeError_1.ApiEdgeError(405, "Method Not Allowed"); } } addQueryStep(query, step, relation = null, output = false) { this.addQueryActions(ApiEdgeAction_1.ApiEdgeActionTriggerKind.AfterEvent, query, step.query, relation, output); query.unshift(step); this.addQueryActions(ApiEdgeAction_1.ApiEdgeActionTriggerKind.BeforeEvent, query, step.query, relation, output); } static buildProvideIdStep(query, currentSegment) { if (currentSegment instanceof ApiRequest_1.EntryPathSegment) { query.unshift(new ExtendContextLiveQueryStep(context => context.id = currentSegment.id)); return false; } else if (currentSegment instanceof ApiRequest_1.RelatedFieldPathSegment) { query.unshift(new ProvideIdQueryStep(currentSegment.relation.relationId)); return true; } else { return false; } } buildCheckStep(query, currentSegment) { if (currentSegment instanceof ApiRequest_1.EntryPathSegment) { query.unshift(new SetResponseQueryStep(new ApiEdgeQueryResponse_1.ApiEdgeQueryResponse({ [currentSegment.edge.idField || Api_1.Api.defaultIdField]: currentSegment.id }))); return false; } else if (currentSegment instanceof ApiRequest_1.RelatedFieldPathSegment) { this.addQueryStep(query, new QueryEdgeQueryStep(new ApiEdgeQuery_1.ApiEdgeQuery(currentSegment.relation.to, ApiEdgeQueryType_1.ApiEdgeQueryType.Get)), currentSegment.relation); } else { throw new ApiEdgeError_1.ApiEdgeError(500, "Not Implemented"); } return ApiQueryBuilder.buildProvideIdStep(query, currentSegment); } buildReadStep(query, currentSegment) { if (currentSegment instanceof ApiRequest_1.RelatedFieldPathSegment) { this.addQueryStep(query, new QueryEdgeQueryStep(new ApiEdgeQuery_1.ApiEdgeQuery(currentSegment.relation.to, ApiEdgeQueryType_1.ApiEdgeQueryType.Get)), currentSegment.relation); } else { this.addQueryStep(query, new QueryEdgeQueryStep(new ApiEdgeQuery_1.ApiEdgeQuery(currentSegment.edge, ApiEdgeQueryType_1.ApiEdgeQueryType.Get))); } return ApiQueryBuilder.buildProvideIdStep(query, currentSegment); } buildEmbedSteps(query, request, lastSegment) { if (request.type === ApiRequest_1.ApiRequestType.Read && (lastSegment instanceof ApiRequest_1.EdgePathSegment || (lastSegment instanceof ApiRequest_1.MethodPathSegment && lastSegment.method.output === ApiEdgeMethod_1.ApiEdgeMethodOutput.List))) { for (let relation of request.context.populatedRelations) { const segment = new ApiRequest_1.EdgePathSegment(relation.to, relation); const embedRequest = new ApiRequest_1.ApiRequest(request.api); embedRequest.path.add(segment); query.unshift(new EmbedQueryQueryStep(this.build(embedRequest), segment, embedRequest)); } } else { for (let relation of request.context.populatedRelations) { let segment; if (relation instanceof OneToManyRelation_1.OneToManyRelation) { segment = new ApiRequest_1.EdgePathSegment(relation.to, relation); } else { segment = new ApiRequest_1.EntryPathSegment(relation.to, 'TBD', relation); } const embedRequest = new ApiRequest_1.ApiRequest(request.api); embedRequest.path.add(segment); query.unshift(new EmbedQueryQueryStep(this.build(embedRequest), segment, embedRequest)); } } } } exports.ApiQueryBuilder = ApiQueryBuilder; //# sourceMappingURL=ApiQueryBuilder.js.map