UNPKG

@inversifyjs/core

Version:

InversifyJs core package

214 lines 10.6 kB
"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