private void WriteInterfaceWithCallToBlock(TypeScriptBlock interfaceWithCallBlock, WebApiAction action, WebApiHttpVerb verb)
        {
            var callArguments = action.BodyParameters;

            var callArgument = callArguments
                               .Select(a => a.GetParameterString(withOptionals: false, interfaceName: true))
                               .SingleOrDefault();

            var callArgumentsList = string.IsNullOrWhiteSpace(callArgument)
                ? "httpConfig?: angular.IRequestShortcutConfig"
                : $"{callArgument}, httpConfig?: angular.IRequestShortcutConfig";

            string typeScriptReturnType, typeScriptTypeForCall;

            action.GetReturnTypes(out typeScriptReturnType, out typeScriptTypeForCall);

            interfaceWithCallBlock
            .AddStatement($"call{typeScriptTypeForCall}({callArgumentsList}): ng.IPromise{typeScriptReturnType};");

            if (Config.EndpointsSupportCaching && verb == WebApiHttpVerb.Get)
            {
                interfaceWithCallBlock
                .AddStatement($"callCached{typeScriptTypeForCall}({callArgumentsList}): ng.IPromise{typeScriptReturnType};");
            }
        }
        private void WriteGetQueryStringToBlock(TypeScriptBlock classBlock, string actionName, WebApiAction action)
        {
            var queryStringParameters = action.QueryStringParameters;

            if (!queryStringParameters.Any())
            {
                return;
            }

            var queryStringBlock = classBlock
                                   .AddAndUseBlock($"{actionName}.prototype.getQueryString = function(): string")
                                   .AddStatement("var parameters: string[] = [];");

            foreach (var routePart in queryStringParameters)
            {
                var argumentName = routePart.Name;

                var block = queryStringBlock;

                var argumentType = routePart.GetTypeScriptType();

                block.AddStatement($"addParameter(parameters, '{argumentName}', this.{argumentName});");
            }

            queryStringBlock
            .AddAndUseBlock("if (parameters.length > 0)")
            .AddStatement("return '?' + parameters.join('&');")
            .Parent
            .AddStatement("return '';");
        }
Exemple #3
0
        public TypeScriptBlock CreateServiceBlock()
        {
            var constructorBlock = new TypeScriptBlock($"{Config.NamespaceOrModuleName} {Config.ServiceNamespace}")
                                   .AddStatement("type BeforeCallHandler = (endpoint: IEndpoint, data, config: ng.IRequestConfig) => ng.IPromise<void>;")
                                   .AddStatement("type AfterCallHandler = <TView> (endpoint: IEndpoint, data, config: ng.IRequestConfig, response: TView) => ng.IPromise<void>;")
                                   .AddAndUseBlock($"export class {Config.ServiceName}")
                                   .AddStatement("static $inject = ['$http', '$q'];")
                                   .AddStatement("static endpointCache = {};", condition: Config.EndpointsSupportCaching)
                                   .AddAndUseBlock("constructor($http: ng.IHttpService, $q: ng.IQService)");

            var serviceBlock = constructorBlock
                               .Parent
                               .AddAndUseBlock("static call<TView>(httpService: ng.IHttpService, qService: ng.IQService, endpoint: IEndpoint, data, httpConfig?: ng.IRequestShortcutConfig)")
                               .AddAndUseBlock("const config =")
                               .AddStatement("method: endpoint._verb,")
                               .AddStatement("url: endpoint.toString(),")
                               .AddStatement("data: data")
                               .Parent
                               .AddStatement("httpConfig && _.extend(config, httpConfig);")
                               .AddStatement("")
                               .AddAndUseBlock($"return qService.all({Config.ServiceName}.onBeforeCallHandlers.map(onBeforeCall => onBeforeCall.handler(endpoint, data, config))).then(before =>", isFunctionBlock: true, terminationString: ";")
                               .AddStatement($"const call = httpService<TView>(config);")
                               .AddAndUseBlock("return call.then(response =>", isFunctionBlock: true, terminationString: ";")
                               .AddStatement("let result = response.data;")
                               .AddStatement($"return qService.all({Config.ServiceName}.onAfterCallHandlers.map(onAfterCall => onAfterCall.handler<TView>(endpoint, data, config, result))).then(after => result);")
                               .Parent
                               .Parent
                               .Parent
                               .AddStatement("private static onBeforeCallHandlers: ({ name: string; handler: BeforeCallHandler; })[] = []")
                               .AddStatement("private static onAfterCallHandlers: ({ name: string; handler: AfterCallHandler; })[] = []")
                               .AddAndUseBlock("static AddBeforeCallHandler = (name: string, handler: BeforeCallHandler) =>")
                               .AddStatement($"{Config.ServiceName}.onBeforeCallHandlers = _.filter({Config.ServiceName}.onBeforeCallHandlers, h => h.name != name);")
                               .AddStatement($"{Config.ServiceName}.onBeforeCallHandlers.push({{ name: name, handler: handler }});")
                               .AddStatement($"return () => {Config.ServiceName}.onBeforeCallHandlers = _.filter({Config.ServiceName}.onBeforeCallHandlers, h => h.name != name);")
                               .Parent
                               .AddAndUseBlock("static AddAfterCallHandler = (name: string, handler: AfterCallHandler) =>")
                               .AddStatement($"{Config.ServiceName}.onAfterCallHandlers = _.filter({Config.ServiceName}.onAfterCallHandlers, h => h.name != name);")
                               .AddStatement($"{Config.ServiceName}.onAfterCallHandlers.push({{ name: name, handler: handler }});")
                               .AddStatement($"return () => {Config.ServiceName}.onAfterCallHandlers = _.filter({Config.ServiceName}.onAfterCallHandlers, h => h.name != name);")
                               .Parent;

            if (Config.EndpointsSupportCaching)
            {
                serviceBlock
                .AddAndUseBlock("static callCached<TView>(httpService: ng.IHttpService, qService: ng.IQService, endpoint: IEndpoint, data, httpConfig?: ng.IRequestShortcutConfig)")
                .AddStatement("var cacheKey = endpoint.toString();")
                .AddAndUseBlock("if (this.endpointCache[cacheKey] == null)")
                .AddAndUseBlock("return this.call<TView>(httpService, qService, endpoint, data, httpConfig).then(result =>", isFunctionBlock: true, terminationString: ";")
                .AddStatement("this.endpointCache[cacheKey] = result;")
                .AddStatement("return this.endpointCache[cacheKey];")
                .Parent
                .Parent
                .AddStatement("const deferred = qService.defer();")
                .AddStatement("deferred.resolve(this.endpointCache[cacheKey]);")
                .AddStatement("return deferred.promise;");
            }

            return(serviceBlock
                   .Parent);
        }
        public TypeScriptBlock CreateEndpointBlock()
        {
            var block = new TypeScriptBlock($"{Config.NamespaceOrModuleName} {Config.EndpointsNamespace}");

            block
            .AddAndUseBlock($"export interface {IEndpoint}")
            .AddStatement("_verb: string;")
            .AddStatement("toString(): string;")
            .Parent
            .AddAndUseBlock("function addParameter(parameters: string[], key: string, value: any)")
            .AddAndUseBlock("if (value == null)")
            .AddStatement("return;")
            .Parent
            .AddAndUseBlock($"if (_.isArray(value))")
            .AddStatement($"var encodedItems = _.map(value, (item: any) => encodeURIComponent(item.toString()));")
            .AddStatement($"_(encodedItems).each(item => parameters.push(`${{key}}=${{item}}`));")
            .Parent
            .AddAndUseBlock("else if (_.isObject(value) && value.getQueryParams)")
            .AddStatement(@"addParameter(parameters, key, value.getQueryParams());")
            .Parent
            .AddAndUseBlock("else if (_.isObject(value))")
            .AddStatement(@"Object.keys(value).forEach((key) => { addParameter(parameters, key, value[key]); });")
            .Parent
            .AddAndUseBlock("else")
            .AddStatement($"parameters.push(`${{key}}=${{encodeURIComponent(value.toString())}}`);");

            return(block);
        }
Exemple #5
0
        private void WriteViewEntry(TypeScriptBlock viewsBlock, ViewNode featureViewNode, bool isChild = false)
        {
            var namespaceBlock = !isChild ? $"export namespace {featureViewNode.Name}" : $"{featureViewNode.Name} : ";
            var featureBlock   = viewsBlock
                                 .AddAndUseBlock(namespaceBlock, terminationString: isChild ? "," : "");

            var viewGroup = Config.UseViewsGroupingNamespace && !isChild
                ? "Views"
                : string.Empty;

            if (!string.IsNullOrEmpty(viewGroup))
            {
                featureBlock = featureBlock.AddAndUseBlock($"export var {viewGroup} = ");
            }

            foreach (var viewEntry in featureViewNode.ViewEntries)
            {
                featureBlock
                .AddStatement($"{viewEntry.Name} : '{viewEntry.Path}',");
            }

            foreach (var childView in featureViewNode.ChildViews)
            {
                WriteViewEntry(featureBlock, childView, isChild: true);
            }
        }
        private void WriteConstructorToBlock(TypeScriptBlock classBlock, WebApiAction action, WebApiHttpVerb verb)
        {
            var actionName = action.GetActionNameForVerb(verb);

            var constructorParameterMappings = action.GetConstructorParameterMappings();

            var areAllParametersOptional = constructorParameterMappings
                                           .All(m => m.IsOptional);

            var optionalString = areAllParametersOptional
                ? "?"
                : string.Empty;

            var constructorBlock = classBlock
                                   .AddAndUseBlock($"constructor(args{optionalString}: I{actionName})");

            foreach (var mapping in constructorParameterMappings)
            {
                constructorBlock
                .AddStatement($"this.{mapping.Name} = args != null ? args.{mapping.Name} : null;");

                if (mapping.TypeMapping?.AutoInitialize ?? false)
                {
                    constructorBlock
                    .AddAndUseBlock($"if (this.{mapping.Name} == null)")
                    .AddStatement($"this.{mapping.Name} = new {mapping.TypeMapping.TypeScriptTypeName}();");
                }
            }
        }
Exemple #7
0
        public void WriteEndpointClassToBlock(TypeScriptBlock endpointsBlock, WebApiController webApiController)
        {
            var controllerBlock = endpointsBlock
                                  .AddAndUseBlock($"export {Config.NamespaceOrModuleName} {webApiController.Name}");

            var actions = webApiController.Actions.Where(a => a.IsMobileAction);

            foreach (var action in actions)
            {
                if (action.BodyParameters.Count > 1)
                {
                    LogMessage($"Multiple conflicting call parameters detected in action [{action.Name}] of controller [{webApiController.Name}]!");
                    LogMessage("Please use [FromBody] or [FromUri] on all non-primitives!");

                    var parameters = action.BodyParameters.Select(bp => $"[{bp.Name}]");
                    LogMessage($"Parameters: {string.Join(" ", parameters)}");
                    LogMessage("");

                    continue;
                }

                foreach (var verb in action.Verbs)
                {
                    var actionName = action.GetActionNameForVerb(verb);

                    var interfaceBlock = controllerBlock
                                         .AddAndUseBlock($"export interface I{actionName}");

                    WriteInterfaceToBlock(interfaceBlock, action);

                    var endpointBlock = controllerBlock
                                        .AddAndUseBlock($"export interface I{actionName}Endpoint extends I{actionName}, IEndpoint");

                    var ctorBlock = controllerBlock
                                    .AddAndUseBlock($"export interface I{actionName}Ctor")
                                    .AddStatement($"new(args?: I{actionName}): I{actionName}Endpoint");

                    var ctorImplBlock = controllerBlock
                                        .AddAndUseBlock($"export var {actionName} : I{actionName}Ctor = <any>(function(args?: I{actionName})", false, ");")
                                        .AddStatement($"this._verb = '{verb.VerbMethod}';");

                    var constructorParameterMappings = action.GetConstructorParameterMappings(ignoreEnumDefinitions: true);
                    foreach (var mapping in constructorParameterMappings)
                    {
                        ctorImplBlock.AddStatement($"this.{mapping.Name} = args != null ? args.{mapping.Name} : null;");
                        if (mapping.TypeMapping?.AutoInitialize ?? false)
                        {
                            ctorImplBlock
                            .AddAndUseBlock($"if (this.{mapping.Name} == null)")
                            .AddStatement($"this.{mapping.Name} = new {mapping.TypeMapping.TypeScriptTypeName}();");
                        }
                    }

                    WriteGetQueryStringToBlock(controllerBlock, actionName, action);

                    WriteToStringToBlock(controllerBlock, actionName, action);
                }
            }
        }
Exemple #8
0
        public TypeScriptBlock WriteViewsToBlock(List <ViewNode> featureViews, TypeScriptBlock viewsBlock)
        {
            foreach (var featureView in featureViews)
            {
                WriteViewEntry(viewsBlock, featureView);
            }

            return(viewsBlock);
        }
        public TypeScriptBlock WriteEnumsToBlock(TypeScriptBlock enumsBlock)
        {
            foreach (var typeDefinition in Enums)
            {
                CreateEnumForType(enumsBlock, typeDefinition);
            }

            return(enumsBlock);
        }
        public void WriteEndpointClassToBlock(TypeScriptBlock endpointBlock, WebApiController webApiController)
        {
            var controllerBlock = endpointBlock
                                  .AddAndUseBlock($"export {Config.NamespaceOrModuleName} {webApiController.Name}");

            TypeScriptBlock serviceBlock = null;

            if (Config.GenerateService)
            {
                serviceBlock = controllerBlock
                               .AddAndUseBlock($"export interface I{webApiController.Name}Service");
            }

            var actions = webApiController.Actions;

            foreach (var action in actions)
            {
                foreach (var verb in action.Verbs)
                {
                    var actionName = action.GetActionNameForVerb(verb);

                    var interfaceBlock = controllerBlock
                                         .AddAndUseBlock($"export interface I{actionName}");

                    WriteInterfaceToBlock(interfaceBlock, action);

                    if (Config.GenerateService)
                    {
                        var interfaceWithCallBlock = controllerBlock
                                                     .AddAndUseBlock($"export interface I{actionName}WithCall extends I{actionName}, {IEndpoint}");

                        WriteInterfaceWithCallToBlock(interfaceWithCallBlock, action, verb);

                        serviceBlock
                        .AddStatement($"{actionName}: (args?: I{actionName}) => I{actionName}WithCall");
                    }

                    var classBlock = controllerBlock
                                     .AddAndUseBlock($"export class {actionName} implements I{actionName}, {IEndpoint}")
                                     .AddStatement($"_verb = '{verb.VerbMethod}';");

                    var constructorParameterMappings = action.GetConstructorParameterMappings();
                    foreach (var constructorParameterMapping in constructorParameterMappings)
                    {
                        classBlock
                        .AddStatement($"{constructorParameterMapping.String};");
                    }

                    WriteConstructorToBlock(classBlock, action, verb);

                    WriteGetQueryStringToBlock(classBlock, action);

                    WriteToStringToBlock(classBlock, action);
                }
            }
        }
        private void WriteInterfaceToBlock(TypeScriptBlock interfaceBlock, WebApiAction action)
        {
            var constructorParameterMappings = action.GetConstructorParameterMappings();

            foreach (var constructorParameterMapping in constructorParameterMappings)
            {
                interfaceBlock
                .AddStatement($"{constructorParameterMapping.StringWithOptionals};");
            }
        }
        public TypeScriptBlock CreateServiceBlock()
        {
            var serviceBlock = new TypeScriptBlock($"{Config.NamespaceOrModuleName} {Config.ServiceNamespace}")
                               .AddAndUseBlock($"export class {Config.ServiceName}")
                               .AddStatement
                               (
                Config.EndpointsSupportCaching
                        ? "static $inject = ['$http', '$q'];"
                        : "static $inject = ['$http'];"
                               )
                               .AddStatement("static $http: ng.IHttpService;")
                               .AddStatement("static $q: ng.IQService;", condition: Config.EndpointsSupportCaching)
                               .AddStatement("static endpointCache = {};", condition: Config.EndpointsSupportCaching)
                               .AddAndUseBlock
                               (
                Config.EndpointsSupportCaching
                        ? "constructor($http: ng.IHttpService, $q: ng.IQService)"
                        : "constructor($http: ng.IHttpService)"
                               )
                               .AddStatement($"{Config.ServiceName}.$http = $http;")
                               .AddStatement($"{Config.ServiceName}.$q = $q;", condition: Config.EndpointsSupportCaching)
                               .Parent
                               .AddAndUseBlock("static call<TView>(endpoint: IEndpoint, data, httpConfig?: angular.IRequestShortcutConfig)")
                               .AddAndUseBlock("const config = ")
                               .AddStatement("method: endpoint._verb,")
                               .AddStatement("url: endpoint.toString(),")
                               .AddStatement("data: data")
                               .Parent
                               .AddStatement("httpConfig && _.extend(config, httpConfig);")
                               .AddStatement("")
                               .AddStatement($"const call = {Config.ServiceName}.$http<TView>(config);")
                               .AddStatement("return call.then(response => response.data);");

            if (Config.EndpointsSupportCaching)
            {
                serviceBlock
                .Parent
                .AddAndUseBlock("static callCached<TView>(endpoint: IEndpoint, data, httpConfig?: angular.IRequestShortcutConfig)")
                .AddStatement("var cacheKey = endpoint.toString();")
                .AddAndUseBlock("if (this.endpointCache[cacheKey] == null)")
                .AddAndUseBlock("return this.call<TView>(endpoint, data, httpConfig).then(result =>", isFunctionBlock: true,
                                terminationString: ";")
                .AddStatement("this.endpointCache[cacheKey] = result;")
                .AddStatement("return this.endpointCache[cacheKey];")
                .Parent
                .Parent
                .AddStatement("const deferred = this.$q.defer();")
                .AddStatement("deferred.resolve(this.endpointCache[cacheKey]);")
                .AddStatement("return deferred.promise;");
            }

            return(serviceBlock
                   .Parent
                   .Parent);
        }
        private void WriteToStringToBlock(TypeScriptBlock classBlock, WebApiAction action)
        {
            var toStringBlock = classBlock
                                .AddAndUseBlock("toString = (): string =>");

            var queryString = action.QueryStringParameters.Any()
                ? " + this.getQueryString()"
                : string.Empty;

            toStringBlock
            .AddStatement($"return `{action.Controller.BaseEndpoint}{action.Endpoint}`{queryString};");
        }
Exemple #14
0
        private void CreateFileForBlock(TypeScriptBlock typeScriptBlock, string outputDirectory, string fileName)
        {
            LogMessage($"Writing {fileName}...");

            CreateOuputDirectory(outputDirectory);

            var filePath = Path.Combine(outputDirectory, fileName);

            using (var endpointFileWriter = new StreamWriter(filePath, false))
            {
                endpointFileWriter.Write(typeScriptBlock.ToString());
            }
        }
        private void WriteInterfaceWithCallToBlock(TypeScriptBlock interfaceWithCallBlock, WebApiAction action)
        {
            var callArguments = action.BodyParameters;

            var callArgumentStrings = callArguments
                                      .Select(a => a.GetParameterString(withOptionals: false, interfaceName: true))
                                      .SingleOrDefault();

            var callArgumentsList = string.Join(", ", callArgumentStrings);

            interfaceWithCallBlock
            .AddStatement($"call<TView>({callArgumentsList}): ng.IPromise<TView>;");
        }
        private void CreateEnumForType(TypeScriptBlock enumsBlock, TypeDefinition typeDefinition)
        {
            var fields = typeDefinition.Fields
                         .Where(f => f.HasConstant && !f.IsSpecialName);

            var enumBlock = enumsBlock
                            .AddAndUseBlock($"export enum {typeDefinition.Name}");

            foreach (var field in fields)
            {
                enumBlock.AddStatement($"{field.Name} = {field.Constant},");
            }
        }
        public void WriteServiceObjectToBlock(TypeScriptBlock serviceBlock, WebApiController webApiController)
        {
            var controllerBlock = serviceBlock
                                  .AddAndUseBlock($"public {webApiController.Name} =");

            var actions = webApiController.Actions;

            for (var a = 0; a < actions.Count; a++)
            {
                var action = actions[a];

                var constructorParameterMappings = action.GetConstructorParameterMappings();

                for (var v = 0; v < action.Verbs.Count; v++)
                {
                    var verb = action.Verbs[v];

                    var actionName = action.GetActionNameForVerb(verb);

                    var isLastActionAndVerb = a == actions.Count - 1 &&
                                              v == action.Verbs.Count - 1;

                    var areAllParametersOptional = constructorParameterMappings
                                                   .All(m => m.IsOptional);

                    var optionalString = areAllParametersOptional
                        ? "?"
                        : string.Empty;

                    var callArgumentDefinition = action.GetCallArgumentDefinition(verb);
                    var callArgumentValue      = action.GetCallArgumentValue(verb);

                    var interfaceFullName         = $"{Config.EndpointsNamespace}.{webApiController.Name}.I{actionName}";
                    var interfaceWithCallFullName = $"{Config.EndpointsNamespace}.{webApiController.Name}.I{actionName}WithCall";
                    var endpointFullName          = $"{Config.EndpointsNamespace}.{webApiController.Name}.{actionName}";

                    controllerBlock
                    .AddAndUseBlock
                    (
                        outer: $"{actionName}: (args{optionalString}: {interfaceFullName}): {interfaceWithCallFullName} =>",
                        isFunctionBlock: false,
                        terminationString: !isLastActionAndVerb ? "," : string.Empty
                    )
                    .AddStatement($"var endpoint = new {endpointFullName}(args);")
                    .AddAndUseBlock("return _.extendOwn(endpoint,", isFunctionBlock: true, terminationString: ";")
                    .AddAndUseBlock($"call<TView>({callArgumentDefinition})")
                    .AddStatement($"return {Config.ServiceName}.call<TView>(this, {callArgumentValue});");
                }
            }
        }
        private void WriteInterfaces(TypeScriptBlock interfacesBlock, InterfaceNode interfaceNode)
        {
            var typeDefinition = interfaceNode.TypeDefinition;

            if (typeDefinition != null)
            {
                WriteInterfaceNode(interfacesBlock, interfaceNode);
            }

            foreach (var derivedInterfaceNode in interfaceNode.DerivedInterfaces)
            {
                WriteInterfaces(interfacesBlock, derivedInterfaceNode);
            }
        }
Exemple #19
0
        private void CreateFileForBlock(TypeScriptBlock typeScriptBlock, string outputDirectory, string fileName)
        {
            CreateOuputDirectory(outputDirectory);

            var filePath = Path.Combine(outputDirectory, fileName);

            //LogMessage($"Writing file [{filePath}]...");

            //stopwatch = Stopwatch.StartNew();

            using (var endpointFileWriter = new StreamWriter(filePath, false))
            {
                endpointFileWriter.Write(typeScriptBlock.ToString());
            }

            //LogMessage($"File [{filePath}] saved! Took {stopwatch.ElapsedMilliseconds}ms.");
        }
Exemple #20
0
        private void CreateGetDescriptionExtensionForType(TypeScriptBlock enumsBlock, TypeDefinition typeDefinition)
        {
            var fields = typeDefinition.Fields
                         .Where(f => f.HasConstant && !f.IsSpecialName);

            var switchBlock = enumsBlock
                              .AddAndUseBlock($"export namespace {typeDefinition.Name}")
                              .AddAndUseBlock($"export function getDescription(enumValue: {typeDefinition.Name})")
                              .AddAndUseBlock("switch (enumValue)");

            foreach (var field in fields)
            {
                var fieldDescription = GetFieldDescription(field);

                switchBlock
                .AddStatement($"case {typeDefinition.Name}.{field.Name}: return \"{fieldDescription}\";");
            }
        }
Exemple #21
0
        private void WriteViewEntry(TypeScriptBlock viewsBlock, ViewNode featureViewNode, bool isChild = false)
        {
            var viewNamespace = Config.UseViewsGroupingNamespace && !isChild
                ? ".Views"
                : string.Empty;

            var featureBlock = viewsBlock
                               .AddAndUseBlock($"export namespace {featureViewNode.Name}{viewNamespace}");

            foreach (var viewEntry in featureViewNode.ViewEntries)
            {
                featureBlock
                .AddStatement($"export const {viewEntry.Name} = '{viewEntry.Path}';");
            }

            foreach (var childView in featureViewNode.ChildViews)
            {
                WriteViewEntry(featureBlock, childView, isChild: true);
            }
        }
Exemple #22
0
        public TypeScriptBlock WriteEnumsToBlock(TypeScriptBlock enumsBlock)
        {
            var sortedEnums = Enums
                              .OrderBy(e => e.Name);

            foreach (var typeDefinition in sortedEnums)
            {
                WriteEnumForType(enumsBlock, typeDefinition);
                if (Config.GenerateEnumDescriptions)
                {
                    CreateGetDescriptionExtensionForType(enumsBlock, typeDefinition);
                }
            }

            foreach (var logMessage in LogMessages)
            {
                LogMessage(logMessage.Value);
            }

            return(enumsBlock);
        }
        private void WriteGetQueryStringToBlock(TypeScriptBlock classBlock, WebApiAction action)
        {
            var queryStringParameters = action.QueryStringParameters;

            if (!queryStringParameters.Any())
            {
                return;
            }

            var queryStringBlock = classBlock
                                   .AddAndUseBlock("private getQueryString = (): string =>")
                                   .AddStatement("var parameters: string[] = [];");

            foreach (var routePart in queryStringParameters)
            {
                var argumentName = routePart.Name;

                var block = queryStringBlock;

                var argumentType = routePart.GetTypeScriptType();

                if (argumentType.IsPrimitive || argumentType.IsEnum)
                {
                    block
                    .AddStatement($"addParameter(parameters, '{argumentName}', this.{argumentName});");
                }
                else
                {
                    block
                    .AddStatement($"addObjectParameters(parameters, this.{argumentName});");
                }
            }

            queryStringBlock
            .AddAndUseBlock("if (parameters.length > 0)")
            .AddStatement("return '?' + parameters.join('&');")
            .Parent
            .AddStatement("return '';");
        }
        public TypeScriptBlock WriteInterfacesToBlock(TypeScriptBlock interfacesBlock)
        {
            WriteInterfaces(interfacesBlock, InterfaceNode);

            return(interfacesBlock);
        }
        private void WriteInterfaceNode(TypeScriptBlock interfacesBlock, InterfaceNode interfaceNode)
        {
            var typeDefinition = interfaceNode.TypeDefinition;

            string implementsString = null;
            string extendsString    = null;

            var iHaveGenericParameters = typeDefinition.HasGenericParameters;

            if (iHaveGenericParameters)
            {
                var genericParameters = typeDefinition.GenericParameters
                                        .Select(p => p.Name);

                implementsString = WrapInAngledBrackets(string.Join(", ", genericParameters));
            }

            var hasBaseClass = interfaceNode.BaseInterface?.TypeDefinition != null;
            var baseTypeName = CleanName(interfaceNode.BaseInterface?.TypeDefinition?.Name);

            if (hasBaseClass)
            {
                var iHaveGenericArguments = typeDefinition.BaseType.IsGenericInstance;
                if (iHaveGenericArguments)
                {
                    var baseTypeInstance = typeDefinition.BaseType as GenericInstanceType;
                    var genericArguments = baseTypeInstance.GenericArguments
                                           .Select(p => p.IsGenericParameter
                            ? p.Name
                            : TypeService.GetTypeScriptType(p.GetElementType(), p.Name).TypeName);

                    extendsString = WrapInAngledBrackets(string.Join(", ", genericArguments));
                }

                var baseTypeHasGenericParameters = typeDefinition.BaseType.HasGenericParameters;
                if (baseTypeHasGenericParameters)
                {
                    var genericParameters = typeDefinition.BaseType.GenericParameters
                                            .Select(p => p.Name);

                    extendsString = WrapInAngledBrackets(string.Join(", ", genericParameters));
                }
            }

            var interfaceExtendsString = hasBaseClass
                ? $" extends I{baseTypeName}{extendsString}"
                : string.Empty;

            var classExtendsString = hasBaseClass
                ? $" extends {baseTypeName}{extendsString}"
                : string.Empty;

            var blockTypeName = CleanName(typeDefinition.Name);

            if (!TypeService.IsValidTypeName(blockTypeName))
            {
                LogMessage($"Interface name [{blockTypeName}] of type [{typeDefinition.FullName}] is invalid!");
                return;
            }

            var classImplementsString =
                $" implements I{blockTypeName}{implementsString}";

            var parameterOrInstanceString = iHaveGenericParameters
                ? implementsString
                : string.Empty;

            var interfaceBlock = interfacesBlock
                                 .AddAndUseBlock($"export interface I{blockTypeName}{parameterOrInstanceString}{interfaceExtendsString}");

            TypeScriptBlock classBlock = null;

            if (Config.GenerateInterfaceClasses)
            {
                classBlock = interfacesBlock
                             .AddAndUseBlock($"export class {blockTypeName}{parameterOrInstanceString}{classExtendsString}{classImplementsString}");
            }

            var things = GetMembers(typeDefinition);

            foreach (var thing in things)
            {
                var thingType = thing.CSharpType.TypeDefinition;

                var union = SameNamedDerivedMembers(thing, interfaceNode)
                            .Select(e => e.CSharpType.TypeDefinition)
                            .ToList();

                union.Add(thingType);

                string interfaceName;
                string typeName;
                if (thing.CSharpType.IsGenericParameter)
                {
                    typeName = interfaceName = thing.CSharpType.GenericParameterName;
                }
                else
                {
                    if (thingType.IsInterface)
                    {
                        continue;
                    }

                    if (union.Count == 1)
                    {
                        var typeScriptType = TypeService.GetTypeScriptType(union[0], thing.Name);

                        interfaceName = typeScriptType.InterfaceName;
                        typeName      = typeScriptType.TypeName;
                    }
                    else
                    {
                        typeName = string.Join(" | ", union
                                               .Select(t =>
                        {
                            var type = TypeService.GetTypeScriptType(t, thing.Name);
                            return(type.TypeName);
                        })
                                               .Distinct());

                        interfaceName = string.Join(" | ", union
                                                    .Select(t =>
                        {
                            var type = TypeService.GetTypeScriptType(t, thing.Name);
                            return(type.InterfaceName);
                        }).Distinct());
                    }
                }

                var thingName = Config.InterfaceMembersInCamelCase
                    ? Helpers.ToCamelCaseFromPascalCase(thing.Name)
                    : thing.Name;

                var collectionString = thing.CSharpType.IsCollection ? "[]" : string.Empty;

                thingName = TypeService.FixIfReservedWord(thingName);

                interfaceBlock
                .AddStatement($"{thingName}: {interfaceName}{collectionString};");

                if (Config.GenerateInterfaceClasses)
                {
                    classBlock
                    .AddStatement($"{thingName}: {typeName}{collectionString};");
                }
            }

            if (Config.GenerateInterfaceClasses)
            {
                if (hasBaseClass)
                {
                    classBlock
                    .AddAndUseBlock("constructor()")
                    .AddStatement("super();");
                }
            }
        }
Exemple #26
0
        private void WriteInterfaces(TypeScriptBlock interfacesBlock, InterfaceNode interfaceNode)
        {
            var typeDefinition = interfaceNode.TypeDefinition;

            if (typeDefinition != null)
            {
                string implementsString = null;
                string extendsString    = null;

                var iHaveGenericParameters = typeDefinition.HasGenericParameters;
                if (iHaveGenericParameters)
                {
                    var genericParameters = typeDefinition.GenericParameters
                                            .Select(p => p.Name);

                    implementsString = WrapInAngledBrackets(string.Join(", ", genericParameters));
                }

                var hasBaseClass = interfaceNode.BaseInterface?.TypeDefinition != null;
                var baseTypeName = CleanName(interfaceNode.BaseInterface?.TypeDefinition?.Name);

                if (hasBaseClass)
                {
                    var iHaveGenericArguments = typeDefinition.BaseType.IsGenericInstance;
                    if (iHaveGenericArguments)
                    {
                        var baseTypeInstance = typeDefinition.BaseType as GenericInstanceType;
                        var genericArguments = baseTypeInstance.GenericArguments
                                               .Select(p => p.IsGenericParameter
                                ? p.Name
                                : TypeService.GetTypeScriptType(p.GetElementType(), p.Name).TypeName);

                        extendsString = WrapInAngledBrackets(string.Join(", ", genericArguments));
                    }

                    var baseTypeHasGenericParameters = typeDefinition.BaseType.HasGenericParameters;
                    if (baseTypeHasGenericParameters)
                    {
                        var genericParameters = typeDefinition.BaseType.GenericParameters
                                                .Select(p => p.Name);

                        extendsString = WrapInAngledBrackets(string.Join(", ", genericParameters));
                    }
                }

                var interfaceExtendsString = hasBaseClass
                    ? $" extends I{baseTypeName}{extendsString}"
                    : string.Empty;

                var classExtendsString = hasBaseClass
                    ? $" extends {baseTypeName}{extendsString}"
                    : string.Empty;

                var blockTypeName = CleanName(typeDefinition.Name);

                var classImplementsString =
                    $" implements I{blockTypeName}{implementsString}, {Config.EndpointsNamespace}.{nameof(IHaveQueryParams)}";

                var parameterOrInstanceString = iHaveGenericParameters
                    ? implementsString
                    : string.Empty;

                var interfaceBlock = interfacesBlock
                                     .AddAndUseBlock($"export interface I{blockTypeName}{parameterOrInstanceString}{interfaceExtendsString}");

                var classBlock = interfacesBlock
                                 .AddAndUseBlock($"export class {blockTypeName}{parameterOrInstanceString}{classExtendsString}{classImplementsString}");

                var things = GetMembers(typeDefinition);

                foreach (var thing in things)
                {
                    var interfaceName = string.Empty;
                    var typeName      = string.Empty;

                    if (thing.CSharpType.IsGenericParameter)
                    {
                        typeName = interfaceName = thing.CSharpType.GenericParameterName;
                    }
                    else
                    {
                        var thingType      = thing.CSharpType.TypeDefinition;
                        var typeScriptType = TypeService.GetTypeScriptType(thingType, thing.Name);

                        interfaceName = typeScriptType.InterfaceName;
                        typeName      = typeScriptType.TypeName;
                    }

                    var thingName = Config.InterfaceMembersInCamelCase
                        ? Helpers.ToCamelCaseFromPascalCase(thing.Name)
                        : thing.Name;

                    var collectionString = thing.CSharpType.IsCollection ? "[]" : string.Empty;

                    interfaceBlock
                    .AddStatement($"{thingName}: {interfaceName}{collectionString};");

                    classBlock
                    .AddStatement($"{thingName}: {typeName}{collectionString};");
                }

                if (hasBaseClass)
                {
                    classBlock
                    .AddAndUseBlock("constructor()")
                    .AddStatement("super();");
                }

                classBlock
                .AddAndUseBlock("getQueryParams()")
                .AddStatement("return this;");
            }

            foreach (var derivedInterfaceNode in interfaceNode.DerivedInterfaces)
            {
                WriteInterfaces(interfacesBlock, derivedInterfaceNode);
            }
        }
Exemple #27
0
        public void WriteServiceObjectToBlock(TypeScriptBlock serviceBlock, WebApiController webApiController)
        {
            var constructorBlock = serviceBlock.Children
                                   .OfType <TypeScriptBlock>()
                                   .First();

            var controllerBlock = serviceBlock
                                  .AddStatement($"public {webApiController.Name}: {Config.EndpointsNamespace}.{webApiController.Name}.I{webApiController.Name}Service = <any>{{}};");

            var actions = webApiController.Actions;

            foreach (var action in actions)
            {
                if (action.BodyParameters.Count > 1)
                {
                    continue;
                }

                var constructorParameterMappings = action.GetConstructorParameterMappings();

                foreach (var verb in action.Verbs)
                {
                    var actionName = action.GetActionNameForVerb(verb);

                    var areAllParametersOptional = constructorParameterMappings
                                                   .All(m => m.IsOptional);

                    var optionalString = areAllParametersOptional
                        ? "?"
                        : string.Empty;

                    var callArgumentDefinition = action.GetCallArgumentDefinition(verb);
                    var callArgumentValue      = action.GetCallArgumentValue(verb);

                    var interfaceFullName         = $"{Config.EndpointsNamespace}.{webApiController.Name}.I{actionName}";
                    var interfaceWithCallFullName = $"{Config.EndpointsNamespace}.{webApiController.Name}.I{actionName}WithCall";
                    var endpointFullName          = $"{Config.EndpointsNamespace}.{webApiController.Name}.{actionName}";

                    string typeScriptReturnType, typeScriptTypeForCall;

                    action.GetReturnTypes(out typeScriptReturnType, out typeScriptTypeForCall);

                    var endpointExtendBlock = constructorBlock
                                              .AddAndUseBlock
                                              (
                        outer: $"this.{webApiController.Name}.{actionName} = (args{optionalString}: {interfaceFullName}): {interfaceWithCallFullName} =>",
                        isFunctionBlock: false,
                        terminationString: ";"
                                              )
                                              .AddStatement($"var endpoint = new {endpointFullName}(args);")
                                              .AddAndUseBlock("return _.extendOwn(endpoint,", isFunctionBlock: true, terminationString: ";")
                                              .AddAndUseBlock
                                              (
                        outer: $"call{typeScriptTypeForCall}({callArgumentDefinition})",
                        isFunctionBlock: false,
                        terminationString: Config.EndpointsSupportCaching ? "," : string.Empty
                                              )
                                              .AddStatement($"return {Config.ServiceName}.call{typeScriptReturnType}($http, $q, this, {callArgumentValue});")
                                              .Parent;

                    if (Config.EndpointsSupportCaching && verb == WebApiHttpVerb.Get)
                    {
                        endpointExtendBlock.AddAndUseBlock($"callCached{typeScriptTypeForCall}({callArgumentDefinition})")
                        .AddStatement($"return {Config.ServiceName}.callCached{typeScriptReturnType}($http, $q, this, {callArgumentValue});");
                    }
                }
            }
        }
Exemple #28
0
        private void WriteInterfaceNode(TypeScriptBlock interfacesBlock, InterfaceNode interfaceNode)
        {
            var typeDefinition = interfaceNode.TypeDefinition;

            string implementsString = null;

            string _interfaceExtendsString = null;
            string _classExtendsString     = null;

            var iHaveGenericParameters = typeDefinition.HasGenericParameters;

            if (iHaveGenericParameters)
            {
                var genericParameters = typeDefinition.GenericParameters
                                        .Select(p => p.Name);

                implementsString = WrapInAngledBrackets(string.Join(", ", genericParameters));
            }

            var hasBaseClass = interfaceNode.BaseInterface?.TypeDefinition != null;
            var baseTypeName = TypeService.CleanGenericName(interfaceNode.BaseInterface?.TypeDefinition?.Name);
            var things       = GetMembers(typeDefinition);

            if (hasBaseClass)
            {
                if (typeDefinition.BaseType is GenericInstanceType baseTypeInstance)
                {
                    var classGenericArguments = baseTypeInstance.GenericArguments
                                                .Select(p => p.IsGenericParameter
                            ? p.Name
                            : TypeService.GetTypeScriptType(p.GetElementType(), p.Name).TypeName);

                    var interfaceGenericArguments = baseTypeInstance.GenericArguments
                                                    .Select(p => p.IsGenericParameter
                            ? p.Name
                            : TypeService.GetTypeScriptType(p.GetElementType(), p.Name).InterfaceName);

                    _classExtendsString     = WrapInAngledBrackets(string.Join(", ", classGenericArguments));
                    _interfaceExtendsString = WrapInAngledBrackets(string.Join(", ", interfaceGenericArguments));
                }
                else
                {
                    var baseTypeHasGenericParameters = typeDefinition.BaseType.HasGenericParameters;
                    if (baseTypeHasGenericParameters)
                    {
                        var genericParameters = typeDefinition.BaseType.GenericParameters
                                                .Select(p => p.Name);

                        _classExtendsString = _interfaceExtendsString = WrapInAngledBrackets(string.Join(", ", genericParameters));
                    }
                }
            }

            var interfaceExtendsString = hasBaseClass
                ? $" extends I{baseTypeName}{_interfaceExtendsString}"
                : string.Empty;

            var classExtendsString = hasBaseClass
                ? $" extends {baseTypeName}{_classExtendsString}"
                : string.Empty;

            var blockTypeName = TypeService.CleanGenericName(typeDefinition.Name);

            if (!TypeService.IsValidTypeName(blockTypeName))
            {
                LogMessage($"Interface name [{blockTypeName}] of type [{typeDefinition.FullName}] is invalid!");
                return;
            }

            var classImplementsString =
                $" implements I{blockTypeName}{implementsString}";

            var parameterOrInstanceString = iHaveGenericParameters
                ? implementsString
                : string.Empty;

            var interfaceBlock = interfacesBlock
                                 .AddAndUseBlock($"export interface I{blockTypeName}{parameterOrInstanceString}{interfaceExtendsString}");

            TypeScriptBlock classBlock = null;

            if (Config.GenerateInterfaceClasses)
            {
                classBlock = interfacesBlock
                             .AddAndUseBlock($"export class {blockTypeName}{parameterOrInstanceString}{classExtendsString}{classImplementsString}");
            }

            foreach (var thing in things)
            {
                var thingType = thing.CSharpType.TypeDefinition;

                var union = SameNamedDerivedMembers(thing, interfaceNode)
                            .Select(e => e.CSharpType.TypeDefinition)
                            .ToList();

                union.Add(thingType);

                string interfaceName;
                string typeName;
                if (thing.CSharpType.IsGenericParameter)
                {
                    typeName = interfaceName = thing.CSharpType.GenericParameterName;
                }
                else if (thing.CSharpType.IsGenericInstance)
                {
                    var baseTypeScriptType = TypeService.GetTypeScriptType(thing.CSharpType.TypeDefinition, thing.Name);

                    if (baseTypeScriptType.IsMappedType)
                    {
                        typeName      = baseTypeScriptType.TypeName;
                        interfaceName = baseTypeScriptType.InterfaceName;
                    }
                    else
                    {
                        var typeNames = string.Join(", ", thing.CSharpType.GenericArgumentTypes
                                                    .Select(t =>
                        {
                            var genericArgumentTypeScriptType = TypeService.GetTypeScriptType(t, thing.Name);
                            return(genericArgumentTypeScriptType.TypeName);
                        }));

                        var interfaceNames = string.Join(", ", thing.CSharpType.GenericArgumentTypes
                                                         .Select(t =>
                        {
                            var genericArgumentTypeScriptType = TypeService.GetTypeScriptType(t, thing.Name);
                            return(genericArgumentTypeScriptType.InterfaceName);
                        }));

                        typeName      = $"{baseTypeScriptType.TypeName}<{typeNames}>";
                        interfaceName = $"{baseTypeScriptType.InterfaceName}<{interfaceNames}>";
                    }
                }
                else
                {
                    if (thingType.IsInterface)
                    {
                        continue;
                    }

                    if (union.Count == 1)
                    {
                        var typeScriptType = TypeService.GetTypeScriptType(union[0], thing.Name);

                        typeName      = typeScriptType.TypeName;
                        interfaceName = typeScriptType.InterfaceName;
                    }
                    else
                    {
                        typeName = string.Join(" | ", union
                                               .Select(t =>
                        {
                            var type = TypeService.GetTypeScriptType(t, thing.Name);
                            return(type.TypeName);
                        })
                                               .Distinct());

                        interfaceName = string.Join(" | ", union
                                                    .Select(t =>
                        {
                            var type = TypeService.GetTypeScriptType(t, thing.Name);
                            return(type.InterfaceName);
                        }).Distinct());
                    }
                }

                var thingName = thing.Name;

                var jsonProperty = thing.CustomAttributes.SingleOrDefault(a => a.AttributeType.Name == "JsonPropertyAttribute");

                if (jsonProperty != null)
                {
                    try
                    {
                        thingName = jsonProperty?.HasProperties ?? false
                            ? jsonProperty.Properties.Single(p => p.Name == "PropertyName").Argument.Value.ToString()
                            : jsonProperty?.HasConstructorArguments ?? false
                                ? jsonProperty.ConstructorArguments.Single().Value.ToString()
                                : thing.Name;
                    }
                    catch
                    {
                        // This is to suppress a assembly load execption which I am unsure of why it is happening
                    }
                }

                if (Config.InterfaceMembersInCamelCase ||
                    typeDefinition.CustomAttributes.Any(a => a.AttributeType.Name == Config.InterfaceCamelCaseCustomAttribute))
                {
                    thingName = Helpers.ToCamelCaseFromPascalCase(thingName);
                }

                var collectionString = Helpers.GetCollectionPostfix(thing.CSharpType.CollectionLevel);

                thingName = TypeService.FixIfReservedWord(thingName);

                interfaceBlock
                .AddStatement($"{thingName}: {interfaceName}{collectionString};");

                if (Config.GenerateInterfaceClasses)
                {
                    classBlock
                    .AddStatement($"{thingName}: {typeName}{collectionString};");
                }
            }

            if (Config.GenerateInterfaceClasses)
            {
                if (hasBaseClass)
                {
                    classBlock
                    .AddAndUseBlock("constructor()")
                    .AddStatement("super();");
                }
            }
        }