Why doesn't VSDoc IntelliSense work inside of a jQuery no-conflict wrapper? - intellisense

/// <reference path="jquery-1.5.vsdoc.js" />
// IntelliSense works here.
function ($, window, document, undefined) { /// <param name="$" type="jQuery" />
// IntelliSense does not work here.
}(jQuery, this, document);
Is there a workaround for Visual Studio 2008? The SP1 hotfix has been applied and is the reason the IntelliSense works outside of the no-conflict wrapper but, inside, no bueno. Some have said to add the param annotation but, alas, that doesn't work either for me.

It's because the definition of the function doesn't know that jQuery means dollar inside of it. Take this for example:
var wrapper = function($, window, document, undefined) {
// this function doesn't know what dollar is
};
// it could be called like this:
wrapper(jQuery, window, document, undefined);
// or like this:
wrapper(1, 2, 3, 4);
Your function cannot know the definition of what you are passing in. It is up to your function to figure that out and make sure your arguments are valid.
The definition of the function and the execution of the function are two separate things. You will not get intellisense for function arguments inside of the function definition.

This works for me in Visual Studio 2010 with the jQuery IntelliSense documentation included from the NuGet package (currently 1.6.1). There is one hack, but this is an example jQuery plugin with full IntelliSense of the jQuery instance.
/// <reference path="/Scripts/jquery-1.6.1.js" />
(function ($) {
/// <param name="$" type="jQuery">
/// Pass me jQuery
/// </param>
// IntelliSense works here.
$(".intellisense_work_here").add(".test", "<strong>it works<strong>");
// Setting this locally enables IntelliSense to work in the .each below.
var $ = $;
$.fn.makeThingsAwesomePlugin = function (options) {
var defaults = {
awesomeness: "really_awesome"
};
var options = $.extend(defaults, options);
return this.each(function () {
// intellisense work here
$(".someting_lame").addClass(options.awesomeness);
});
};
})(jQuery);

Related

How to show XML comments of class properties in Swagger (MVC 6 Web API JsonResult)

I've added XML comments to my class members but Swagger won't show them in the UI. Am I doing something wrong?
UPDATE: It looks like you can't document your model classes in
Swashbuckle (5.5.3) with #ApiModel and #ApiModelProperty annotations and the
xml comments don't work either.
public class DataController : ApiController
{
[Route("api/GetData")]
[SwaggerResponse(HttpStatusCode.OK, Type = typeof(MyData))]
public System.Web.Mvc.JsonResult GetData()
{
MyData myData = new MyData();
return new System.Web.Mvc.JsonResult
{
Data = myData
};
}
}
public class MyData
{
/// <summary>
/// My code
/// </summary>
public string code;
/// <summary>
/// My name
/// </summary>
public string name;
}
Swagger configuration
public class SwaggerConfig
{
public static void Register()
{
var thisAssembly = typeof(SwaggerConfig).Assembly;
GlobalConfiguration.Configuration
.EnableSwagger(c =>
{
// By default, the service root url is inferred from the request used to access the docs.
// However, there may be situations (e.g. proxy and load-balanced environments) where this does not
// resolve correctly. You can workaround this by providing your own code to determine the root URL.
//
//c.RootUrl(req => GetRootUrlFromAppConfig());
// If schemes are not explicitly provided in a Swagger 2.0 document, then the scheme used to access
// the docs is taken as the default. If your API supports multiple schemes and you want to be explicit
// about them, you can use the "Schemes" option as shown below.
//
//c.Schemes(new[] { "http", "https" });
// Use "SingleApiVersion" to describe a single version API. Swagger 2.0 includes an "Info" object to
// hold additional metadata for an API. Version and title are required but you can also provide
// additional fields by chaining methods off SingleApiVersion.
//
c.SingleApiVersion("v1", "WDSJSONServer");
// If your API has multiple versions, use "MultipleApiVersions" instead of "SingleApiVersion".
// In this case, you must provide a lambda that tells Swashbuckle which actions should be
// included in the docs for a given API version. Like "SingleApiVersion", each call to "Version"
// returns an "Info" builder so you can provide additional metadata per API version.
//
//c.MultipleApiVersions(
// (apiDesc, targetApiVersion) => ResolveVersionSupportByRouteConstraint(apiDesc, targetApiVersion),
// (vc) =>
// {
// vc.Version("v2", "Swashbuckle Dummy API V2");
// vc.Version("v1", "Swashbuckle Dummy API V1");
// });
// You can use "BasicAuth", "ApiKey" or "OAuth2" options to describe security schemes for the API.
// See https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md for more details.
// NOTE: These only define the schemes and need to be coupled with a corresponding "security" property
// at the document or operation level to indicate which schemes are required for an operation. To do this,
// you'll need to implement a custom IDocumentFilter and/or IOperationFilter to set these properties
// according to your specific authorization implementation
//
//c.BasicAuth("basic")
// .Description("Basic HTTP Authentication");
//
// NOTE: You must also configure 'EnableApiKeySupport' below in the SwaggerUI section
//c.ApiKey("apiKey")
// .Description("API Key Authentication")
// .Name("apiKey")
// .In("header");
//
//c.OAuth2("oauth2")
// .Description("OAuth2 Implicit Grant")
// .Flow("implicit")
// .AuthorizationUrl("http://petstore.swagger.wordnik.com/api/oauth/dialog")
// //.TokenUrl("https://tempuri.org/token")
// .Scopes(scopes =>
// {
// scopes.Add("read", "Read access to protected resources");
// scopes.Add("write", "Write access to protected resources");
// });
// Set this flag to omit descriptions for any actions decorated with the Obsolete attribute
//c.IgnoreObsoleteActions();
// Each operation be assigned one or more tags which are then used by consumers for various reasons.
// For example, the swagger-ui groups operations according to the first tag of each operation.
// By default, this will be controller name but you can use the "GroupActionsBy" option to
// override with any value.
//
//c.GroupActionsBy(apiDesc => apiDesc.HttpMethod.ToString());
// You can also specify a custom sort order for groups (as defined by "GroupActionsBy") to dictate
// the order in which operations are listed. For example, if the default grouping is in place
// (controller name) and you specify a descending alphabetic sort order, then actions from a
// ProductsController will be listed before those from a CustomersController. This is typically
// used to customize the order of groupings in the swagger-ui.
//
//c.OrderActionGroupsBy(new DescendingAlphabeticComparer());
// If you annotate Controllers and API Types with
// Xml comments (http://msdn.microsoft.com/en-us/library/b2s063f7(v=vs.110).aspx), you can incorporate
// those comments into the generated docs and UI. You can enable this by providing the path to one or
// more Xml comment files.
//
c.IncludeXmlComments(GetXmlCommentsPath());
// Swashbuckle makes a best attempt at generating Swagger compliant JSON schemas for the various types
// exposed in your API. However, there may be occasions when more control of the output is needed.
// This is supported through the "MapType" and "SchemaFilter" options:
//
// Use the "MapType" option to override the Schema generation for a specific type.
// It should be noted that the resulting Schema will be placed "inline" for any applicable Operations.
// While Swagger 2.0 supports inline definitions for "all" Schema types, the swagger-ui tool does not.
// It expects "complex" Schemas to be defined separately and referenced. For this reason, you should only
// use the "MapType" option when the resulting Schema is a primitive or array type. If you need to alter a
// complex Schema, use a Schema filter.
//
//c.MapType<ProductType>(() => new Schema { type = "integer", format = "int32" });
// If you want to post-modify "complex" Schemas once they've been generated, across the board or for a
// specific type, you can wire up one or more Schema filters.
//
//c.SchemaFilter<ApplySchemaVendorExtensions>();
// In a Swagger 2.0 document, complex types are typically declared globally and referenced by unique
// Schema Id. By default, Swashbuckle does NOT use the full type name in Schema Ids. In most cases, this
// works well because it prevents the "implementation detail" of type namespaces from leaking into your
// Swagger docs and UI. However, if you have multiple types in your API with the same class name, you'll
// need to opt out of this behavior to avoid Schema Id conflicts.
//
//c.UseFullTypeNameInSchemaIds();
// Alternatively, you can provide your own custom strategy for inferring SchemaId's for
// describing "complex" types in your API.
//
//c.SchemaId(t => t.FullName.Contains('`') ? t.FullName.Substring(0, t.FullName.IndexOf('`')) : t.FullName);
// Set this flag to omit schema property descriptions for any type properties decorated with the
// Obsolete attribute
//c.IgnoreObsoleteProperties();
// In accordance with the built in JsonSerializer, Swashbuckle will, by default, describe enums as integers.
// You can change the serializer behavior by configuring the StringToEnumConverter globally or for a given
// enum type. Swashbuckle will honor this change out-of-the-box. However, if you use a different
// approach to serialize enums as strings, you can also force Swashbuckle to describe them as strings.
//
//c.DescribeAllEnumsAsStrings();
// Similar to Schema filters, Swashbuckle also supports Operation and Document filters:
//
// Post-modify Operation descriptions once they've been generated by wiring up one or more
// Operation filters.
//
//c.OperationFilter<AddDefaultResponse>();
//
// If you've defined an OAuth2 flow as described above, you could use a custom filter
// to inspect some attribute on each action and infer which (if any) OAuth2 scopes are required
// to execute the operation
//
//c.OperationFilter<AssignOAuth2SecurityRequirements>();
// Post-modify the entire Swagger document by wiring up one or more Document filters.
// This gives full control to modify the final SwaggerDocument. You should have a good understanding of
// the Swagger 2.0 spec. - https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md
// before using this option.
//
//c.DocumentFilter<ApplyDocumentVendorExtensions>();
// In contrast to WebApi, Swagger 2.0 does not include the query string component when mapping a URL
// to an action. As a result, Swashbuckle will raise an exception if it encounters multiple actions
// with the same path (sans query string) and HTTP method. You can workaround this by providing a
// custom strategy to pick a winner or merge the descriptions for the purposes of the Swagger docs
//
//c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());
// Wrap the default SwaggerGenerator with additional behavior (e.g. caching) or provide an
// alternative implementation for ISwaggerProvider with the CustomProvider option.
//
//c.CustomProvider((defaultProvider) => new CachingSwaggerProvider(defaultProvider));
})
.EnableSwaggerUi(c =>
{
// Use the "InjectStylesheet" option to enrich the UI with one or more additional CSS stylesheets.
// The file must be included in your project as an "Embedded Resource", and then the resource's
// "Logical Name" is passed to the method as shown below.
//
//c.InjectStylesheet(containingAssembly, "Swashbuckle.Dummy.SwaggerExtensions.testStyles1.css");
// Use the "InjectJavaScript" option to invoke one or more custom JavaScripts after the swagger-ui
// has loaded. The file must be included in your project as an "Embedded Resource", and then the resource's
// "Logical Name" is passed to the method as shown above.
//
//c.InjectJavaScript(thisAssembly, "Swashbuckle.Dummy.SwaggerExtensions.testScript1.js");
// The swagger-ui renders boolean data types as a dropdown. By default, it provides "true" and "false"
// strings as the possible choices. You can use this option to change these to something else,
// for example 0 and 1.
//
//c.BooleanValues(new[] { "0", "1" });
// By default, swagger-ui will validate specs against swagger.io's online validator and display the result
// in a badge at the bottom of the page. Use these options to set a different validator URL or to disable the
// feature entirely.
//c.SetValidatorUrl("http://localhost/validator");
//c.DisableValidator();
// Use this option to control how the Operation listing is displayed.
// It can be set to "None" (default), "List" (shows operations for each resource),
// or "Full" (fully expanded: shows operations and their details).
//
//c.DocExpansion(DocExpansion.List);
// Specify which HTTP operations will have the 'Try it out!' option. An empty paramter list disables
// it for all operations.
//
//c.SupportedSubmitMethods("GET", "HEAD");
// Use the CustomAsset option to provide your own version of assets used in the swagger-ui.
// It's typically used to instruct Swashbuckle to return your version instead of the default
// when a request is made for "index.html". As with all custom content, the file must be included
// in your project as an "Embedded Resource", and then the resource's "Logical Name" is passed to
// the method as shown below.
//
//c.CustomAsset("index", containingAssembly, "YourWebApiProject.SwaggerExtensions.index.html");
// If your API has multiple versions and you've applied the MultipleApiVersions setting
// as described above, you can also enable a select box in the swagger-ui, that displays
// a discovery URL for each version. This provides a convenient way for users to browse documentation
// for different API versions.
//
//c.EnableDiscoveryUrlSelector();
// If your API supports the OAuth2 Implicit flow, and you've described it correctly, according to
// the Swagger 2.0 specification, you can enable UI support as shown below.
//
//c.EnableOAuth2Support(
// clientId: "test-client-id",
// clientSecret: null,
// realm: "test-realm",
// appName: "Swagger UI"
// //additionalQueryStringParams: new Dictionary<string, string>() { { "foo", "bar" } }
//);
// If your API supports ApiKey, you can override the default values.
// "apiKeyIn" can either be "query" or "header"
//
//c.EnableApiKeySupport("apiKey", "header");
});
}
protected static string GetXmlCommentsPath()
{
return System.String.Format(#"{0}\bin\WebApiSwagger.XML", System.AppDomain.CurrentDomain.BaseDirectory);
}
}
I've created the XML comments file but comments are not seen in the Model section of Swagger UI.
In my case, it was because my models are in a different project than the service.
I added another IncludeXmlComments call in Startup.cs and it works:
c.IncludeXmlComments(xmlPath2); // add Other proj xml comments file, this is needed because it's in a different project.
Just adding the comments isn't enough.
You need to build an XML documentation file and you need to tell swagger where to find it in your configuration.
Go to your project build properties and check XML Documentation File
Then in your swagger config, add the following
c.IncludeXmlComments(string.Format(#"{0}\bin\MyApi.XML",
System.AppDomain.CurrentDomain.BaseDirectory))
Also works if you convert your fields to properties.
public class MyData
{
/// <summary>
/// My code
/// </summary>
public string code { get; set; }
}
The problem seems to be that Swagger does not document fields, only properties. And if you check the generated XML you will see that the variable will have a F or P prefix. https://msdn.microsoft.com/en-us/library/fsbx0t7x(v=vs.110).aspx
I was struggling with that too. What helped me was setting it as a property.
/// <summary>
/// Radius of the circle
/// </summary>
[DataMember]
public double radius;
/// <summary>
/// Colour of the circle
/// </summary>
[DataMember]
public double farba { get; set; }
/// <summary>
/// Some random variable
/// </summary>
[DataMember]
double random { get; set; }
Result
Circle {
radius (number, optional),
farba (number, optional): Colour of the circle ,
random (number, optional)
}
As you can see only public property has description.
Hope it will help.
As other answers state, you need to add documentation files for any projects that house the objects you want comments for. Here is my solution for safely adding more projects.
In the project file, add this line to the opening <PropertyGroup>:
<GenerateDocumentationFile>true</GenerateDocumentationFile>
Then in your swagger config section of the code:
var xmlFiles = new[]
{
//the current assembly (the web api)
$"{Assembly.GetExecutingAssembly().GetName().Name}.xml",
//another assembly housing MyEntityView. Add more lines like this to add more assemblies
$"{Assembly.GetAssembly(typeof(MyEntityView))?.GetName().Name}.xml"
};
foreach(var xmlFile in xmlFiles)
{
var xmlCommentFile = xmlFile;
var xmlCommentsFullPath = Path.Combine(AppContext.BaseDirectory, xmlCommentFile);
if (File.Exists(xmlCommentsFullPath))
{
options.IncludeXmlComments(xmlCommentsFullPath);
}
}

Import an AMD JS library in a TypeScript file

I'm stuck with the right way to import an AMD JavaScript library (https://github.com/dcodeIO/bytebuffer.js) into a TypeScript file.
I found its - not up-to-date - type definition (https://github.com/SINTEF-9012/Proto2TypeScript/commit/0889dccbf6048f116551a73e77d75dd83553cfe6), but actually I was not able to find a way to use it and have the library loaded by RequireJS.
This is the code I'm using:
/// <amd-dependency path="Scripts/bytebuffer" />
var ByteBuffer = require( 'Scripts/bytebuffer' );
import protocols = require( 'protocols' );
export class Pippo
{
readPayload( payload: ArrayBuffer, ECType: string ): any
{
var ECStruct = new protocols.ECStruct( ECType );
var bb = new ByteBuffer()
.writeIString( "Hello world!" )
.flip();
console.log( bb.readIString() + " from bytebuffer.js" );
}
}
The two modules protocols and bytebuffer are loaded correctly, but actually I cannot see members of instance bb in Visual Studio. If I put the line
/// <reference path="scripts/typings/bytebuffer/bytebuffer.d.ts" />
and comment
//var ByteBuffer = require( 'Scripts/bytebuffer' );
of course I can see methods and properties of bb, but the module is not loaded at runtime.
Is there a way to have the ByteBuffer.js loaded by RequireJS with the possibility to see its members in VS?
Thanks
There is a syntax for declaring the interface of external modules:
declare module 'amd/module/name' {
// module definition, probably with:
exports = thingToExport;
}
In your case it should probably be:
declare module 'Scripts/bytebuffer' {
exports = ByteBuffer;
}
Put this after the bytebuffer.d.ts file!!! Also see "Writing .d.ts files" in the handbook.
In my case the /// <amd-dependency> and /// <reference> stuff were also redundant - you may want to try it too, to simplify your code.

What is dojo equivalent of $('body')?

The following methods returns object
dojo.body()
but we can not addClass on it (or any other operation) ?
Please see http://dojotoolkit.org/reference-guide/1.9/dojo/query.html for information on using dojo/query especialy with AMD. dojo/query returns NodeList - an array just like $('.someSelector'). Note that to do something like $('body').addClass('class') you'll need to require dojo/NodeList-dom.
So basic example of adding class using dojo/query (and AMD) would be
require(["dojo/query", "dojo/NodeList-dom"], function(query){
query("body").addClass('class');
});
For the full list of NodeList methods see Dojo docs. Methods could be defined in different modules so look for "Defined by dojo/NodeList-dom" below method name.
In the current versions of Dojo (see 1.9), the technology has changed. To access the body, one would now code:
require(["dojo/_base/window"], function(win) {
var myBody = win.body();
});
To add a class, one would code:
require(["dojo/_base/window", "dojo/dom-class", function(win, domClass) {
domClass.add(win.body(), "someClass");
});
See also:
http://dojotoolkit.org/reference-guide/1.9/dojo/_base/window.html#dojo-base-window-body
http://dojotoolkit.org/reference-guide/1.9/dojo/dom-class.html#dojo-dom-class-add

Catching and logging MVC4 message about "Minification failed. Returning unminified contents"

There are a number of questions on StackOverflow that talk about getting the Minification failed. Returning unminified contents error from the MVC4 minification.
I'd like to know if there is a way to be notified about this error when it happens and to be able to log it.
It is nice that when there is an error the bundler returns the original contents so my site doesn't break, but I would like to know about these errors automatically rather than having to visit each css/js bundle url to see if there is an error.
So that logic is actually in the implementation of the default transforms that Script/StyleBundle are using. If you want to catch those errors yourself, you can change the transforms on your bundles to something that surfaces those errors:
So to actually detect the errors, you would have to manually enumerate all of your bundles (to trigger them to get generated), and also be able to listen to errors that happened (so the GenerateErrorResponse equivalent below would need to report any errors to someplace that you would see)
Here's what JsMinify does in its process for reference:
/// <summary>
/// Transforms the bundle contents by applying javascript minification
/// </summary>
/// <param name="context">The <see cref="BundleContext"/> object that contains state for both the framework configuration and the HTTP request.</param>
/// <param name="response">A <see cref="BundleResponse"/> object containing the bundle contents.</param>
public virtual void Process(BundleContext context, BundleResponse response) {
if (!context.EnableInstrumentation) {
Minifier min = new Minifier();
// NOTE: Eval immediate treatment is needed for WebUIValidation.js to work properly after minification
// NOTE: CssMinify does not support important comments, so we are going to strip them in JS minification as well
string minifiedJs = min.MinifyJavaScript(response.Content, new CodeSettings() { EvalTreatment = EvalTreatment.MakeImmediateSafe, PreserveImportantComments = false });
if (min.ErrorList.Count > 0) {
GenerateErrorResponse(response, min.ErrorList);
}
else {
response.Content = minifiedJs;
}
}
response.ContentType = JsContentType;
}

Node.js prevent function inspection (toString)

When javascript is run in the browser there is no need to try and hide function code because it is downloaded and viewable in source.
When run on the server the situation changes. There are use cases such as api where you want to provide users with functions to call without allowing them to view the code that which is run.
On our specific case we want to execute user submitted javascript inside node. We are able to sandbox node.js api however we would like to add our own api to this sandbox without users being able to toString the function to view the code which is run.
Does anyone have a pattern or know of a way of preventing users from outputting a functions code?
Update:
Here is a full solution (i believe) based on the accepted answer below. Please note that although this is demonstrated using client side code. You would not use this client side as someone can see the contents of your hidden function by simply reading the downloaded code (although it may provide some basic slow down to inspect the code if you have used a minify).
This is meant for server side use where you want to allow users to run api code within a sandbox env but not allow them to view what the api's do. The sandbox in this code is only to demonstrate the point. It is not an actual sandbox implementation.
// function which hides another function by returning an anonymous
// function which calls the hidden function (ie. places the hidden
// function in a closure to enable access when the wraped function is passed to the sandbox)
function wrapFunc(funcToHide) {
var shownFunc = function() {
funcToHide();
};
return shownFunc;
}
// function whose contents you want to hide
function secretFunc() {
alert('hello');
}
// api object (will be passed to the sandbox to enable access to
// the hidden function)
var apiFunc = wrapFunc(secretFunc);
var api = {};
api.apiFunc = apiFunc;
// sandbox (not an actual sandbox implementation - just for demo)
(function(api) {
console.log(api);
alert(api.apiFunc.toString());
api.apiFunc();
})(api);
If you wrap a callback in a function, you can use another function in that scope which is actually hidden from the callback scope, thus:
function hideCall(funcToHide) {
var hiddenFunc = funcToHide;
var shownFunc = function() {
hiddenFunc();
};
return shownFunc;
}
Then run thusly
var shtumCallBack = hideCall(secretSquirrelFunc);
userCode.tryUnwindingThis(shtumCallBack);
The userCode scope will not be able to access secretSquirrelFunc except to call it, because the scope it would need is that of the hideCall function which is not available.