@inversifyjs/core
Version:
InversifyJs core package
214 lines • 10.6 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.plan = plan;
const common_1 = require("@inversifyjs/common");
const BindingConstraintsImplementation_1 = require("../../binding/models/BindingConstraintsImplementation");
const BindingType_1 = require("../../binding/models/BindingType");
const SingleInmutableLinkedList_1 = require("../../common/models/SingleInmutableLinkedList");
const ClassElementMetadataKind_1 = require("../../metadata/models/ClassElementMetadataKind");
const ResolvedValueElementMetadataKind_1 = require("../../metadata/models/ResolvedValueElementMetadataKind");
const buildFilteredServiceBindings_1 = require("./buildFilteredServiceBindings");
const checkServiceNodeSingleInjectionBindings_1 = require("./checkServiceNodeSingleInjectionBindings");
const handlePlanError_1 = require("./handlePlanError");
const isInstanceBindingNode_1 = require("./isInstanceBindingNode");
const isPlanServiceRedirectionBindingNode_1 = require("./isPlanServiceRedirectionBindingNode");
function plan(params) {
try {
const tags = new Map();
if (params.rootConstraints.tag !== undefined) {
tags.set(params.rootConstraints.tag.key, params.rootConstraints.tag.value);
}
const bindingConstraintsList = new SingleInmutableLinkedList_1.SingleInmutableLinkedList({
elem: {
name: params.rootConstraints.name,
serviceIdentifier: params.rootConstraints.serviceIdentifier,
tags,
},
previous: undefined,
});
const bindingConstraints = new BindingConstraintsImplementation_1.BindingConstraintsImplementation(bindingConstraintsList.last);
const filteredServiceBindings = (0, buildFilteredServiceBindings_1.buildFilteredServiceBindings)(params, bindingConstraints);
const serviceNodeBindings = [];
const serviceNode = {
bindings: serviceNodeBindings,
parent: undefined,
serviceIdentifier: params.rootConstraints.serviceIdentifier,
};
serviceNodeBindings.push(...buildServiceNodeBindings(params, bindingConstraintsList, filteredServiceBindings, serviceNode));
if (!params.rootConstraints.isMultiple) {
(0, checkServiceNodeSingleInjectionBindings_1.checkServiceNodeSingleInjectionBindings)(serviceNode, params.rootConstraints.isOptional ?? false, bindingConstraints);
const [planBindingNode] = serviceNodeBindings;
serviceNode.bindings = planBindingNode;
}
return {
tree: {
root: serviceNode,
},
};
}
catch (error) {
(0, handlePlanError_1.handlePlanError)(params, error);
}
}
function buildInstancePlanBindingNode(params, binding, bindingConstraintsList, parentNode) {
const classMetadata = params.getClassMetadata(binding.implementationType);
const childNode = {
binding: binding,
classMetadata,
constructorParams: [],
parent: parentNode,
propertyParams: new Map(),
};
const subplanParams = {
autobindOptions: params.autobindOptions,
getBindings: params.getBindings,
getClassMetadata: params.getClassMetadata,
node: childNode,
servicesBranch: params.servicesBranch,
setBinding: params.setBinding,
};
return subplan(subplanParams, bindingConstraintsList);
}
function buildPlanServiceNodeFromClassElementMetadata(params, bindingConstraintsList, elementMetadata) {
if (elementMetadata.kind === ClassElementMetadataKind_1.ClassElementMetadataKind.unmanaged) {
return undefined;
}
const serviceIdentifier = common_1.LazyServiceIdentifier.is(elementMetadata.value)
? elementMetadata.value.unwrap()
: elementMetadata.value;
const updatedBindingConstraintsList = bindingConstraintsList.concat({
name: elementMetadata.name,
serviceIdentifier,
tags: elementMetadata.tags,
});
const bindingConstraints = new BindingConstraintsImplementation_1.BindingConstraintsImplementation(updatedBindingConstraintsList.last);
const filteredServiceBindings = (0, buildFilteredServiceBindings_1.buildFilteredServiceBindings)(params, bindingConstraints);
const serviceNodeBindings = [];
const serviceNode = {
bindings: serviceNodeBindings,
parent: params.node,
serviceIdentifier,
};
serviceNodeBindings.push(...buildServiceNodeBindings(params, updatedBindingConstraintsList, filteredServiceBindings, serviceNode));
if (elementMetadata.kind === ClassElementMetadataKind_1.ClassElementMetadataKind.singleInjection) {
(0, checkServiceNodeSingleInjectionBindings_1.checkServiceNodeSingleInjectionBindings)(serviceNode, elementMetadata.optional, bindingConstraints);
const [planBindingNode] = serviceNodeBindings;
serviceNode.bindings = planBindingNode;
}
return serviceNode;
}
function buildPlanServiceNodeFromResolvedValueElementMetadata(params, bindingConstraintsList, elementMetadata) {
const serviceIdentifier = common_1.LazyServiceIdentifier.is(elementMetadata.value)
? elementMetadata.value.unwrap()
: elementMetadata.value;
const updatedBindingConstraintsList = bindingConstraintsList.concat({
name: elementMetadata.name,
serviceIdentifier,
tags: elementMetadata.tags,
});
const bindingConstraints = new BindingConstraintsImplementation_1.BindingConstraintsImplementation(updatedBindingConstraintsList.last);
const filteredServiceBindings = (0, buildFilteredServiceBindings_1.buildFilteredServiceBindings)(params, bindingConstraints);
const serviceNodeBindings = [];
const serviceNode = {
bindings: serviceNodeBindings,
parent: params.node,
serviceIdentifier,
};
serviceNodeBindings.push(...buildServiceNodeBindings(params, updatedBindingConstraintsList, filteredServiceBindings, serviceNode));
if (elementMetadata.kind === ResolvedValueElementMetadataKind_1.ResolvedValueElementMetadataKind.singleInjection) {
(0, checkServiceNodeSingleInjectionBindings_1.checkServiceNodeSingleInjectionBindings)(serviceNode, elementMetadata.optional, bindingConstraints);
const [planBindingNode] = serviceNodeBindings;
serviceNode.bindings = planBindingNode;
}
return serviceNode;
}
function buildResolvedValuePlanBindingNode(params, binding, bindingConstraintsList, parentNode) {
const childNode = {
binding: binding,
params: [],
parent: parentNode,
};
const subplanParams = {
autobindOptions: params.autobindOptions,
getBindings: params.getBindings,
getClassMetadata: params.getClassMetadata,
node: childNode,
servicesBranch: params.servicesBranch,
setBinding: params.setBinding,
};
return subplan(subplanParams, bindingConstraintsList);
}
function buildServiceNodeBindings(params, bindingConstraintsList, serviceBindings, parentNode) {
const serviceIdentifier = (0, isPlanServiceRedirectionBindingNode_1.isPlanServiceRedirectionBindingNode)(parentNode)
? parentNode.binding.targetServiceIdentifier
: parentNode.serviceIdentifier;
params.servicesBranch.push(serviceIdentifier);
const planBindingNodes = [];
for (const binding of serviceBindings) {
switch (binding.type) {
case BindingType_1.bindingTypeValues.Instance: {
planBindingNodes.push(buildInstancePlanBindingNode(params, binding, bindingConstraintsList, parentNode));
break;
}
case BindingType_1.bindingTypeValues.ResolvedValue: {
planBindingNodes.push(buildResolvedValuePlanBindingNode(params, binding, bindingConstraintsList, parentNode));
break;
}
case BindingType_1.bindingTypeValues.ServiceRedirection: {
const planBindingNode = buildServiceRedirectionPlanBindingNode(params, bindingConstraintsList, binding, parentNode);
planBindingNodes.push(planBindingNode);
break;
}
default:
planBindingNodes.push({
binding: binding,
parent: parentNode,
});
}
}
params.servicesBranch.pop();
return planBindingNodes;
}
function buildServiceRedirectionPlanBindingNode(params, bindingConstraintsList, binding, parentNode) {
const childNode = {
binding,
parent: parentNode,
redirections: [],
};
const bindingConstraints = new BindingConstraintsImplementation_1.BindingConstraintsImplementation(bindingConstraintsList.last);
const filteredServiceBindings = (0, buildFilteredServiceBindings_1.buildFilteredServiceBindings)(params, bindingConstraints, {
customServiceIdentifier: binding.targetServiceIdentifier,
});
childNode.redirections.push(...buildServiceNodeBindings(params, bindingConstraintsList, filteredServiceBindings, childNode));
return childNode;
}
function subplan(params, bindingConstraintsList) {
if ((0, isInstanceBindingNode_1.isInstanceBindingNode)(params.node)) {
return subplanInstanceBindingNode(params, params.node, bindingConstraintsList);
}
else {
return subplanResolvedValueBindingNode(params, params.node, bindingConstraintsList);
}
}
function subplanInstanceBindingNode(params, node, bindingConstraintsList) {
const classMetadata = node.classMetadata;
for (const [index, elementMetadata,] of classMetadata.constructorArguments.entries()) {
node.constructorParams[index] =
buildPlanServiceNodeFromClassElementMetadata(params, bindingConstraintsList, elementMetadata);
}
for (const [propertyKey, elementMetadata] of classMetadata.properties) {
const planServiceNode = buildPlanServiceNodeFromClassElementMetadata(params, bindingConstraintsList, elementMetadata);
if (planServiceNode !== undefined) {
node.propertyParams.set(propertyKey, planServiceNode);
}
}
return params.node;
}
function subplanResolvedValueBindingNode(params, node, bindingConstraintsList) {
const resolvedValueMetadata = node.binding.metadata;
for (const [index, elementMetadata,] of resolvedValueMetadata.arguments.entries()) {
node.params[index] = buildPlanServiceNodeFromResolvedValueElementMetadata(params, bindingConstraintsList, elementMetadata);
}
return params.node;
}
//# sourceMappingURL=plan.js.map