Serge van den Oever [Macaw]

SharePoint RIP. Azure, Node.js, hybrid mobile apps

  • Cordova – file-transfer, unzip and present adventures

    For a hybrid project I have a very simple requirement: download zip file, unzip it, serve content on a page from artifacts (html text, images).

    I started with Intel XDK, an environment I did some other work with. A great integrated development environment, but some of its big problems: lagging behind in version of Cordova, fixed set of selected plugins, no possibility to include other plugins. Because I wanted to unzip, I tried it with a Javascript only solution zip.js. The problem I had was that it worked if I downloaded the zip file over http using importHttpContent(), but I could’t get it working with loading from the local file system. Another problem I had was with where files ended up on different devices: in / on wp8, on /storage/sdcard0 on Android, and on iOS in even another location.

    I decided to go with plain Cordova, with the command-line commands. That was a good decision. It was now possible to use the latest version (3.4 at time of writing), and use the new file and file-transfer plugins that now support a huge improvement to hybrid development: the cdvfile protocol. Files can now be addressed with respect to one multi-platform root: cdvfile://, rather than through device-specific paths. There is also a great plugin available to unzip that understands the new cdvfile:// notation as well. I ended up with a simple example to showcase the download, unzip and present case. To get it working execute the following commands with a Cordova 3.4 installation:

    1. cordova create Cordova-TransferUnzipPresent com.svdoever.tranferunzippresent TransferUnzipPresent
    2. cd Cordova-TransferUnzipPresent
    3. cordova platform add android
    4. cordova plugin add org.apache.cordova.file
    5. cordova plugin add org.apache.cordova.file-transfer
    6. cordova plugin add org.chromium.zip
    7. Replace code in www\index.html with the code below
    8. cordova emulate android

    Works with iOS platform as well. The zip plugin does not work on wp8 (yet).

    The code:

    <!-- Code by Serge van den Oever, http://weblogs.asp.net/soever -->
    <!-- Using Cordova 3.4 with the following plugins: -->
    <!-- 'org.apache.cordova.file' (version 1.0.1), 'org.apache.cordova.file-transfer' (0.4.2), 'org.chromium.zip' (2.0.0)  -->
    <!DOCTYPE html>
    <html>
    <head>
        <title>Cordova Download Unzip Display Sample</title>
        <meta http-equiv="Content-type" content="text/html; charset=utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=0">
        <script src="cordova.js"></script>
    </head>
    
    <body>
    <button id="btnLoad">Load</button>
    <button id="btnUnzip">Unzip</button>
    <hr/>
    <div id="statusPlace"></div>
    <hr/>
    <img id="imgPlace" src="http://lorempixel.com/320/200">
    <br/>
    <div id="txtPlace">TEXT COMES HERE</div>
    
    <script type="application/javascript">
        document.addEventListener("deviceready", onDeviceReady, false);
    
        function registerHandlers() {
            document.getElementById("btnLoad").onclick = function() {
                var that = this,
                        App = new DownloadApp(),
                        fileName = "ft-p.zip",
                        uri = encodeURI("https://dl.dropboxusercontent.com/u/7197720/ftpack.zip"),
                        folderName = "content";
                console.log("load button clicked");
                document.getElementById("statusPlace").innerHTML += "<br/>Loading: " + uri;
                App.load(uri, folderName, fileName,
                        /*progress*/function(percentage) { document.getElementById("statusPlace").innerHTML += "<br/>" + percentage + "%"; },
                        /*success*/function(entry) { document.getElementById("statusPlace").innerHTML += "<br/>Zip saved to: " + entry.toURL(); },
                        /*fail*/function() { document.getElementById("statusPlace").innerHTML += "<br/>Failed load zip: " + that.uri; }
                );
            };
            document.getElementById("btnUnzip").onclick = function() {
                var that = this,
                        App = new DownloadApp(),
                        fileName = "ft-p.zip",
                        folderName = "content";
                console.log("zip button clicked");
                App.unzip(folderName, fileName,
                        /*success*/function() { alert("Unzipped and assigned"); },
                        /*fail*/function(error) { alert("Unzip failed: " + error.code); }
                );
            };
        }
    
        function onDeviceReady() {
            // navigator.splashscreen.hide();
            document.getElementById("statusPlace").innerHTML += "<br/>deviceready event received";
            registerHandlers();
        }
    
        var DownloadApp = function() {
        }
    
        DownloadApp.prototype = {
            load: function(uri, folderName, fileName, progress, success, fail) {
                var that = this;
                that.progress = progress;
                that.success = success;
                that.fail = fail;
                filePath = "";
    
                that.getFilesystem(
                        function(fileSystem) {
                            console.log("GotFS");
                            that.getFolder(fileSystem, folderName, function(folder) {
                                filePath = folder.toURL() + "/" + fileName;
                                that.transferFile(uri, filePath, progress, success, fail);
                            }, function(error) {
                                console.log("Failed to get folder: " + error.code);
                                typeof that.fail === 'function' && that.fail(error);
                            });
                        },
                        function(error) {
                            console.log("Failed to get filesystem: " + error.code);
                            typeof that.fail === 'function' && that.fail(error);
                        }
                );
            },
    
            getFilesystem:function (success, fail) {
                window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
                window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, success, fail);
            },
    
            getFolder: function (fileSystem, folderName, success, fail) {
                fileSystem.root.getDirectory(folderName, {create: true, exclusive: false}, success, fail)
            },
    
            transferFile: function (uri, filePath, progress, success, fail) {
                var that = this;
                that.progress = progress;
                that.success = success;
                that.fail = fail;
    
                var transfer = new FileTransfer();
                transfer.onprogress = function(progressEvent) {
                    if (progressEvent.lengthComputable) {
                        var perc = Math.floor(progressEvent.loaded / progressEvent.total * 100);
                        typeof that.progress === 'function' && that.progress(perc); // progression on scale 0..100 (percentage) as number
                    } else {
                    }
                };
    
                transfer.download(
                        uri,
                        filePath,
                        function(entry) {
                            console.log("File saved to: " + entry.toURL());
                            typeof that.success === 'function' && that.success(entry);
                        },
                        function(error) {
                            console.log("An error has occurred: Code = " + error.code);
                            console.log("download error source " + error.source);
                            console.log("download error target " + error.target);
                            console.log("download error code " + error.code);
                            typeof that.fail === 'function' && that.fail(error);
                        }
                );
            },
    
            unzip: function(folderName, fileName, success, fail) {
                var that = this;
                that.success = success;
                that.fail = fail;
    
                zip.unzip("cdvfile://localhost/persistent/" + folderName + "/" + fileName,
                          "cdvfile://localhost/persistent/" + folderName,
                        function(code) {
                            console.log("result: " + code);
                            that.getFilesystem(
                                    function(fileSystem) {
                                        console.log("gotFS");
                                        that.getFolder(fileSystem, folderName + "/ftpack", function (folder) {
                                            document.getElementById("imgPlace").src = folder.nativeURL + "/img.jpg";
                                            folder.getFile("text.html", {create: false}, function (fileEntry) {
                                                fileEntry.file(function(file) {
                                                    var reader = new FileReader();
                                                    reader.onloadend = function (evt) {
                                                        console.log("Read as text");
                                                        console.log(evt.target.result);
                                                        document.getElementById("txtPlace").innerHTML = evt.target.result;
                                                        typeof that.success === ' function && that.success();'
                                                    };
                                                    reader.readAsText(file);
                                                }, function(error) {
                                                    console.log("Failed to get file");
                                                    typeof that.fail === 'function' && that.fail(error);
                                                });
                                            }, function (error) {
                                                console.log("failed to get file: " + error.code);
                                                typeof that.fail === 'function' && that.fail(error);
                                            });
                                        }, function (error) {
                                            console.log("failed to get folder: " + error.code);
                                            typeof that.fail === 'function' && that.fail(error);
                                        });
                                    }, function(error) {
                                        console.log("failed to get filesystem: " + error.code);
                                        typeof that.fail === 'function' && that.fail(error);
                                    });
                        }
                );
            }
        }
    </script>
    </body>
    </html>
    
  • AngularJS–don’t use self-closing div tags

    I had a piece of code that gave strange results in AngularJS. The issue was that I used a self closing <div /> tag instead of <div>…</div>. Self closing div tags are not supported in HTML5. The complete code can be found at http://stackoverflow.com/questions/21552560/angularjs-bug-in-ng-include-when-not-using-jquery and the plunker http://plnkr.co/edit/O3NSb2VEwAEDrkmtoKZ6?p=preview.

    My wrong code was written as:

    <script id="paragraphTmpl.html" type="text/ng-template">
        <h4>{{paragraph.Title}}</h4>
        <!-- comment line below to have the paragraphs render correctly --> 
        <div ng-bind-html="trustAsHtml(paragraph.Content)"/>
        <ng-include ng-repeat="paragraph in paragraph.Paragraphs" 
                    src="'paragraphTmpl.html'">
    </script>
    
    <div>
        <h3>{{chaptercontent.Title}}</h3>
    
        <div ng-bind-html="trustAsHtml(chaptercontent.Content)"/>
        <ng-include ng-repeat="paragraph in chaptercontent.Paragraphs" 
                    src="'paragraphTmpl.html'"/>
    </div>
    It works fine when jQuery is included, but not when you use the AngularJS JQLite implementation.
    When <div ng-bind-html="trustAsHtml(chaptercontent.Content)"></div> is used, the code works correctly.
  • Webstorm – great IDE for web development

    I’m really interested in front-end web development, and although Visual Studio 2013 is the main IDE in our company I’m really impressed by Webstorm from JetBrains, the guys behind Resharper. It is a full featured web development IDE for under $50. Although I’m impressed by the better support of Visual Studio 2013 for web development, Webstorm feels like “exactly made” for web development.The reason I favor Webstorm right now is that Visual Studio is pushing you too much into the Microsoft way, with server side code, web.config files etc. I want to build single page apps, front-end (JavaScript and Typescript) code only, talking to services, that can be hosted on any web server, or even drop box, and can also be embedded into a Phonegap mobile application if needed.

    And the great thing: it works on OSX and Windows, I have my code on dropbox and can hop from mac to windows without changing a thing.

    Check out http://www.jetbrains.com/webstorm/

    Note: I’m in no way affiliated with, or sponsered by, JetBrains, just a happy and impressed user.

  • Visual Studio Online “Monaco”: the backend is in node.js

    Probably to some surprise for some of you: the backend of Monaco is written in node.js, and actually a quite new version of node.js: version v0.10.21 (at the time of writing this post). Because it is running on IIS, it uses iisnode to run the site.

    The backend uses the following node modules:

    The code base itself consists of the following files:

    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/availableLanguages.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/config/db.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/config/home.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/config/logger.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/config/tools.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/config/workspaces.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/config.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/config/config.contribution.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/contributions.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/event/event.contribution.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/event/event.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/event/eventImpl.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/experiment/experiment.contribution.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/feedback/feedback.contribution.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/files/files.contribution.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/files/files.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/files/stat.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/git/git.config.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/git/git.contribution.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/git/git.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/output/output.contribution.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/process/commands/any.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/process/commands/azure.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/process/commands/commands.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/process/commands/express.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/process/commands/fs.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/process/commands/git.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/process/commands/help.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/process/commands/init.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/process/commands/jake.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/process/commands/mocha.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/process/commands/monaco-editor.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/process/commands/msbuild.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/process/commands/msdeploy/echo.bat
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/process/commands/msdeploy/Microsoft.Web.Delegation.dll
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/process/commands/msdeploy/Microsoft.Web.Deployment.dll
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/process/commands/msdeploy/msdeploy.exe
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/process/commands/msdeploy/msdeploy.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/process/commands/msdeploy/publish.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/process/commands/nake.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/process/commands/nodejs.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/process/commands/npm.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/process/commands/nuget.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/process/commands/ps.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/process/commands/setup.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/process/commands/tsc.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/process/process.contribution.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/process/shell/parser.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/process/shell/shell.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/search/fileSearch.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/search/index/index.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/search/search.contribution.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/search/search.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/search/searchApp.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/search/textSearch.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/strongbox/strongbox.contribution.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/telemetry/telemetry.contribution.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/telemetry/telemetry.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/telemetry/telemetryClient.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/tfs/tfs.contribution.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/tfs/tfs.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/typescript/build/tsc.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/typescript/lib/lib.d.ts
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/typescript/lib/typescriptServices.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/typescript/routes/filesRoute.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/typescript/routes/graphRoute.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/typescript/routes/projectRoute.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/typescript/service/references.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/typescript/service/requireRunner.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/typescript/service/resolver.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/typescript/service/serverLanguageService.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/contrib/typescript/typescript.contribution.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/controller/eventChannel.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/controller/events.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/controller/log.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/controller/monaco.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/controller/ping.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/controller/public.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/controller/workspace.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/home/.gitconfig
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/home/bin/cred.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/home/bin/cred.sh
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/home/empty.cmd
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/home/empty.sh
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/assert.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/async.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/cache.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/cli.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/collections.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/config.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/db/db.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/db/engines/inmemory.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/db/engines/jsondb.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/encoding.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/errors.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/eventBus.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/events.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/extcp.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/extfs.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/extnet.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/extpath.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/flow.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/http2.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/import.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/injector.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/injectorService.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/jshtm.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/logger.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/mime.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/nls.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/node.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/performance.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/pfs.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/process/process.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/process/ProcessUtils.cs
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/process/processUtils.dll
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/promises.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/route.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/siteextension.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/stream.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/strings.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/system.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/temp.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/types.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/typeScript/tsc.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/typeScript/typescript.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/typeScript/typescriptServices.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/utils.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/uuid.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/watcher/fileWatcher.cs
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/watcher/fileWatcher.dll
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/watcher/watcher.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/watcher/watcher.win32.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/zip/zip.cs
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/zip/zip.dll
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/lib/zip/zip.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/middleware/access.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/middleware/cache.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/middleware/logger.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/middleware/security.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/middleware/upload.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/middleware.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/model/modelDb.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/model/workspace.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/monaco.impl.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/monaco.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/platform.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/routes.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/run-siteextension.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/run.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/version.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/view/dashboard.jshtm
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/view/error.jshtm
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/view/log.jshtm
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/view/monaco.jshtm
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server/view/workbench.jshtm
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/server.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/web.config

  • Visual Studio Online “Monaco”: supported languages and file types

    Diving into Visual Studio online I was wondering which languages / file types are supported. After some hacking I came to the following list: bat, coffeescript, cpp, csharp, css, fsharp, handlebars, html, ini, jade, java, javascript, jshtm, json, less, lua, markdown, php, powershell, python, razor, ruby, typescript, vb, xml.

    Not all languages will probably be supported out of the box, it probably depends on your msbuild / jake / whatever build script.

    I based this list on the following “support files” in the Monaco source code:

    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/bat/bat.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/bat/bat.nls.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/bat/bat.nls.keys.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/coffeescript/coffeescript.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/coffeescript/coffeescript.nls.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/coffeescript/coffeescript.nls.keys.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/cpp/cpp.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/cpp/cpp.nls.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/cpp/cpp.nls.keys.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/csharp/csharp.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/csharp/csharp.nls.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/csharp/csharp.nls.keys.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/css/css.css
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/css/css.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/css/css.nls.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/css/css.nls.keys.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/css/cssWorker.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/css/cssWorker.nls.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/css/cssWorker.nls.keys.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/css/lib/beautify-css.license.txt
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/css/lib/cssLib.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/css/lib/cssLib.nls.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/css/lib/cssLib.nls.keys.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/css/lib/csslint.license.txt
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/css/lib/OSSREADME.txt
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/css/monacoParticipant.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/css/monacoParticipant.nls.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/css/monacoParticipant.nls.keys.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/css/README
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/fsharp/fsharp.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/fsharp/fsharp.nls.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/fsharp/fsharp.nls.keys.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/handlebars/handlebars.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/handlebars/handlebars.nls.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/handlebars/handlebars.nls.keys.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/html/html.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/html/html.nls.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/html/html.nls.keys.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/html/htmlWorker.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/html/htmlWorker.nls.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/html/htmlWorker.nls.keys.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/ini/ini.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/ini/ini.nls.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/ini/ini.nls.keys.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/jade/jade.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/jade/jade.nls.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/jade/jade.nls.keys.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/java/java.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/java/java.nls.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/java/java.nls.keys.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/javascript/javascript.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/javascript/javascript.nls.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/javascript/javascript.nls.keys.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/javascript/javascriptWorker.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/javascript/javascriptWorker.nls.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/javascript/javascriptWorker.nls.keys.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/jshtm/jshtm.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/jshtm/jshtm.nls.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/jshtm/jshtm.nls.keys.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/json/json.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/json/json.nls.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/json/json.nls.keys.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/json/jsonWorker.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/json/jsonWorker.nls.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/json/jsonWorker.nls.keys.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/less/less.css
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/less/less.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/less/less.nls.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/less/less.nls.keys.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/less/lessWorker.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/less/lessWorker.nls.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/less/lessWorker.nls.keys.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/less/parser/less.grammar.txt
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/lib/beautify-html.license.txt
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/lib/OSSREADME.txt
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/lua/lua.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/lua/lua.nls.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/lua/lua.nls.keys.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/markdown/markdown.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/markdown/markdown.nls.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/markdown/markdown.nls.keys.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/nullWorker.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/nullWorker.nls.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/nullWorker.nls.keys.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/php/OSSREADME.txt
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/php/php.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/php/php.nls.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/php/php.nls.keys.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/php/phpWorker.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/php/phpWorker.nls.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/php/phpWorker.nls.keys.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/powershell/powershell.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/powershell/powershell.nls.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/powershell/powershell.nls.keys.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/python/python.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/python/python.nls.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/python/python.nls.keys.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/python/pythonWorker.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/python/pythonWorker.nls.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/python/pythonWorker.nls.keys.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/razor/razor.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/razor/razor.nls.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/razor/razor.nls.keys.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/ruby/ruby.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/ruby/ruby.nls.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/ruby/ruby.nls.keys.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/ruby/rubyWorker.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/ruby/rubyWorker.nls.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/ruby/rubyWorker.nls.keys.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/typescript/lib/lib.d.ts
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/typescript/lib/typescriptServices.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/typescript/lib/typescriptServices.nls.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/typescript/lib/typescriptServices.nls.keys.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/typescript/participants/nlsParticipant.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/typescript/participants/nlsParticipant.nls.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/typescript/participants/nlsParticipant.nls.keys.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/typescript/typescript.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/typescript/typescript.nls.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/typescript/typescript.nls.keys.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/typescript/typescriptWorker2.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/typescript/typescriptWorker2.nls.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/typescript/typescriptWorker2.nls.keys.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/vb/vb.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/vb/vb.nls.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/vb/vb.nls.keys.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/vb/vbWorker.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/vb/vbWorker.nls.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/vb/vbWorker.nls.keys.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/vwd.webinfo
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/xml/xml.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/xml/xml.nls.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/xml/xml.nls.keys.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/xml/xmlWorker.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/xml/xmlWorker.nls.js
    D:\Program Files (x86)\SiteExtensions/Monaco/1.0.0-20131104/client/86a9221e/vs/languages/xml/xmlWorker.nls.keys.js

  • Hybrid mobile applications–what is it–what are the tools

    As mentioned in a previous blog post I am going to write some observation posts on development tools that can be used to write hybrid mobile applications. What is a hybrid mobile application in my thoughts? I see it as a:

    • platform specific native “shell” application
    • utilizes a browser control as its rendering surface
    • provides an API that gives access to native device functions (camera, contacts, …)
    • makes the API available to Javascript running in the browser control
    • the application functionality is written using HTML, CSS and Javascript in the spirit of building web apps
    • the application specific code can be bundled and ”injected” into the shell application
    • the functionality provided by the shell application can be extended with plugins that are written for the native platform and provides additional API functions to the Javascript running in the browser control

    There are many other possible ways to think about hybrid mobile apps, but the slice of approaches I’m most interested in is the one where you utilize web standards to build your mobile applications. There is a great blog post by Udayan Banerjee called Cross-Platform Hybrid Mobile Application Development – a Tool Comparison where he goes into great detail on the huge set of different tools that are available in the broad sense of hybrid mobile apps. He divides the tools into:

    • Mobile Web (JavaScript-CSS library), (see this)
    • Visual Tool (No access to Code), (see this)
    • App Generator (Native application for multiple platforms), (see this)
    • Hybrid App (Leverages embedded browser control), (see this)
    • Game Builder (see this)

    I will only discuss tools that are in the Hybrid App space.

    See the following post for some of my observations on tools in this space: (not written in the specified order)

    • Cordova (to be written)
    • PhoneGap / PhoneGap Build (to be written)
    • Intel XDK (to be written)
    • Red-gate Nomad (to be written)
    • Icenium (to be written)
    • DevExpress DevExtreme (to be written)

    I will update the links when the posts are written.

  • Developing mobile apps–too many options?

    It is unbelievable how many companies jumped on the mobile app development bandwagon.

    In the early days life was easy. When you developed for iOS (iPhone, iPod Touch and iPad) you bought a Mac, downloaded XCode and started programming in Objective-C. For Android you grabbed a PC, downloaded the Android SDK and Java was your best friend. And for Windows Phone (yes it still exists) you downloaded a version of Visual Studio, the Windows Phone SDK and you started to hack away in good old C#.

    The new trend for mobile apps that don’t ask too much from the platform (say non-game, and non-multimedia applications) is to develop them cross-platform without the need to rewrite the applications multiple times in different languages.

    Wikipedia gives a nice overview of some of the available mobile application development platforms at http://en.wikipedia.org/wiki/Mobile_application_development. And this overview is even far from complete.

    Within the development platforms you see broadly two options for developing your cross-platform mobile apps:

    1. Development in one language for a native UI, where the interaction patterns are phone specific
    2. Development one one language for a cross-platform UI, where the interaction patterns are app specific

    Of course there are all kind of mixes of the above two options, for example Appcelerator where you develop your code in Javascript with a platform independent API to create native UI elements, or a lot of JavaScript libraries like PhoneJS en KendoUI where you render web technology widgets using HTML, CSS and Javascript that try to behave like native widgets.

    I am very interested in the Xamarin approach where you can use C# as the common app language, but create a native UI per platform. But I am also a strong believer of the “hybrid” development approach where you develop your application using HTML, CSS and Javascript, and wrap your “application” in a host application for packaging and deploying to the app stores.

    In some following posts I will dive into a few of the development options for creating hybrid mobile applications using tooling like:

    All above options have their roots in the Cordova project.

  • Azure Mobile Services: revealing the internals

    I think this is an interesting blog post if you want to know how azure Mobile Services is working. Don’t forget to check the link at the end of this post to see all source code of Azure Mobile Services:-)

    The Azure Mobile Services documentation is … suboptimal. It is unclear in which context our server side scripts are running, which node.js modules are available, and which node.js modules are already loaded. The best way to get an idea on what is going on is by looking at the source code that is running inside Azure Mobile Services. In this post I will show some of the node.js scripts running Azure Mobile Services. These scripts are the scripts running today, but they may change as we speak. At least the scripts will give us some ideas what is happening.

    I will try to comment on some things that we see, but I’m absolutely no node.js expert, I just started to dive into this technology.

    Azure mobile services in built on top of node.js which is running in IIS8 using iisnode. To support the web features like the API’s Azure Mobile Services uses the Express web application framework for node.

    When you look at the getting started guide of Express you see that you need to “… Create a file named app.js or server.js”. If you look at the used Web.config file this is exactly the starting point that is on Azure Mobile Services as defined in the handlers section: <handlers> <add name="iisnode" path="app.js" verb="*" modules="iisnode" /> </handlers>

    Source-code of Web.config:

    <?xml version="1.0"?>
    <configuration>
      <system.web>
        <customErrors mode="Off" />
      </system.web>
      <system.webServer>
        <httpErrors errorMode="Detailed" />
        <iisnode devErrorsEnabled="false" loggingEnabled="false" />
        <handlers>
          <add name="iisnode" path="app.js" verb="*" modules="iisnode" />
        </handlers>
        <rewrite>
          <rules>
            <rule name="favicon">
              <match url="favicon.ico" />
              <action type="CustomResponse" statusCode="404" />
            </rule>
            <!-- Serve a robots.txt file which disallows everything -->
            <rule name="robots" stopProcessing="true">
              <match url="^robots.txt" />
              <action type="Rewrite" url="static/robots.txt" />
            </rule>
            <rule name="landingpage" stopProcessing="true">
              <match url="^$" />
              <action type="Rewrite" url="static/default.htm" />
            </rule>
            <!-- This rule allows IIS to serve the /static/client directory natively -->
            <rule name="client" stopProcessing="true">
              <match url="^client/(.*)" />
              <action type="Rewrite" url="static/client/{R:1}" />
            </rule>
            <!-- This rule routes everything to app.js, except for direct
                 requests to app.js, as in /app.js/debug node debugging. -->
            <rule name="app">
              <match url="/*" />
              <action type="Rewrite" url="app.js" />
            </rule>
          </rules>
        </rewrite>
      </system.webServer>
      <location path="runtime">
        <system.web>
          <authorization>
            <deny users="*" />
          </authorization>
        </system.web>
      </location>
      <!-- The below settings are for local testing only. The web config transforms remove all of
           these settings when the deploy package is built, since placeholder setting values
           arent needed in Antares -->
      <appSettings>
        <!-- This setting must remain, so the package process can set the version -->
        <add key="RuntimeVersion" value="Zumo.Main.0.1.6.3017.Runtime" />
      </appSettings>
    </configuration>

    What more do we see in the Web.config file:

    • There is a static folder that is used for serving static files
    • /robots.txt is mapped to static/robots.txt
    • the root (/) of the Mobile Services Web site is mapped to static/default.htm
    • the client JavaScript libraries are mapped to /static/client/*
      • /client/MobileServices.Web-1.0.0.js
      • /client/MobileServices.Web-1.0.0.min.js

    Ok, so everything kicks off in a node.js file call app.js. So lets get started here...

    Source-code of app.js:

    // ----------------------------------------------------------------------------
    // Copyright (c) Microsoft Corporation. All rights reserved.
    // ----------------------------------------------------------------------------
    //
    // The Zumo runtime. Creates an instance of a Zumo server with options determined
    // by env variables and starts listening on the port designated by the PORT env
    // variable.
    require('./runtime/server.js').createServer(process.env).listen(process.env.PORT);

    From this simple app.js script a module called server.js is loaded, and in this module the createServer() function is called with a lot of environment settings.

    In general these environment settings look like: (I anonymized some values)

    {
      "APP_POOL_CONFIG": "C:\\DWASFiles\\Sites\\<NAME-OF-AZURE-MOBILE-SERVICES-SITE>\\Config\\applicationhost.config",
      "APP_POOL_ID": "<NAME-OF-AZURE-MOBILE-SERVICES-SITE>",
      "PROCESSOR_ARCHITEW6432": "AMD64",
      "TMP": "C:\\DWASFiles\\Sites\\<NAME-OF-AZURE-MOBILE-SERVICES-SITE>\\Temp",
      "TEMP": "C:\\DWASFiles\\Sites\\<NAME-OF-AZURE-MOBILE-SERVICES-SITE>\\Temp",
      "ApplicationName": "<NAME-OF-AZURE-MOBILE-SERVICES-SITE>",
      "APPSETTING_ApplicationName": "<NAME-OF-AZURE-MOBILE-SERVICES-SITE>",
      "UserConnectionString": "<MY-DATABASE-CONNECTIONSTRING>",
      "APPSETTING_UserConnectionString": "<MY-DATABASE-CONNECTIONSTRING>",
      "LogServiceURL": "https://<NAME-OF-LOGSERVICE-SERVER>.cloudapp.net/",
      "APPSETTING_LogServiceURL": "https://<NAME-OF-LOGSERVICE-SERVER>.cloudapp.net/",
      "LogServiceToken": "<MY-LOGSERVICE-TOKEN>",
      "APPSETTING_LogServiceToken": "<MY-LOGSERVICE-TOKEN>",
      "ApnsCertificateMode": "None",
      "APPSETTING_ApnsCertificateMode": "None",
      "ApnsCertificatePassword": "",
      "APPSETTING_ApnsCertificatePassword": "",
      "ApplicationKey": "<MY-APPLICATIONKEY>",
      "APPSETTING_ApplicationKey": "<MY-APPLICATIONKEY>",
      "ApplicationMasterKey": "<MY-APPLICATIONMASTERKEY>",
      "APPSETTING_ApplicationMasterKey": "<MY-APPLICATIONMASTERKEY>",
      "LogLevel": "Error",
      "APPSETTING_LogLevel": "Error",
      "DynamicSchemaEnabled": "True",
      "APPSETTING_DynamicSchemaEnabled": "True",
      "PreviewFeatures": "[]",
      "APPSETTING_PreviewFeatures": "[]",
      "ApplicationSystemKey": "<MY-APPLICATIONSYSTEMKEY>",
      "APPSETTING_ApplicationSystemKey": "<MY-APPLICATIONSYSTEMKEY>",
      "ScmType": "None",
      "APPSETTING_ScmType": "None",
      "APPDATA": "C:\\DWASFiles\\Sites\\<NAME-OF-AZURE-MOBILE-SERVICES-SITE>\\AppData",
      "LOCALAPPDATA": "C:\\DWASFiles\\Sites\\<NAME-OF-AZURE-MOBILE-SERVICES-SITE>\\LocalAppData",
      "PROGRAMDATA": "C:\\DWASFiles\\Sites\\<NAME-OF-AZURE-MOBILE-SERVICES-SITE>\\ProgramData",
      "ALLUSERSPROFILE": "C:\\DWASFiles\\Sites\\<NAME-OF-AZURE-MOBILE-SERVICES-SITE>\\ProgramData",
      "USERPROFILE": "C:\\DWASFiles\\Sites\\<NAME-OF-AZURE-MOBILE-SERVICES-SITE>\\UserProfile",
      "HOME": "C:\\DWASFiles\\Sites\\<NAME-OF-AZURE-MOBILE-SERVICES-SITE>\\VirtualDirectory0",
      "windows_tracing_flags": "",
      "windows_tracing_logfile": "",
      "Path": "D:\\Windows\\system32;D:\\Windows;D:\\Windows\\System32\\Wbem;D:\\Windows\\System32\\WindowsPowerShell\\v1.0\\;D:\\Users\\OnStartAdmin\\AppData\\Roaming\\npm;D:\\Program Files (x86)\\nodejs\\;D:\\Program Files (x86)\\Mercurial\\;D:\\Program Files (x86)\\Microsoft ASP.NET\\ASP.NET Web Pages\\v1.0\\;D:\\Program Files (x86)\\PHP\\v5.3;",
      "CommonProgramFiles": "D:\\Program Files (x86)\\Common Files",
      "CommonProgramFiles(x86)": "D:\\Program Files (x86)\\Common Files",
      "CommonProgramW6432": "D:\\Program Files\\Common Files",
      "COMPUTERNAME": "<MY-COMPUTERNAME>",
      "ComSpec": "D:\\Windows\\system32\\cmd.exe",
      "FP_NO_HOST_CHECK": "NO",
      "NUMBER_OF_PROCESSORS": "8",
      "OS": "Windows_NT",
      "PATHEXT": ".COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC",
      "PROCESSOR_ARCHITECTURE": "x86",
      "PROCESSOR_IDENTIFIER": "AMD64 Family 16 Model 4 Stepping 2, AuthenticAMD",
      "PROCESSOR_LEVEL": "16",
      "PROCESSOR_REVISION": "0402",
      "ProgramFiles": "D:\\Program Files (x86)",
      "ProgramFiles(x86)": "D:\\Program Files (x86)",
      "ProgramW6432": "D:\\Program Files",
      "PSModulePath": "D:\\Windows\\system32\\WindowsPowerShell\\v1.0\\Modules\\",
      "PUBLIC": "D:\\Users\\Public",
      "SystemDrive": "D:",
      "SystemRoot": "D:\\Windows",
      "USERDOMAIN": "WORKGROUP",
      "USERNAME": "<MY-USERNAME>",
      "windir": "D:\\Windows",
      "PORT": "\\\\.\\pipe\\b4b47d62-dcfe-426b-a239-6a4755a06f29",
      "IISNODE_VERSION": "0.2.6",
      "RuntimeVersion": "Zumo.Main.0.1.6.3221.Runtime"
    }

    Hey, Azure runs on 8-processors 64-bit AMD processors!

    But lets not get distracted, the real thing gets going in server.js

    Source-code of ./runtime/server.js:

    // ----------------------------------------------------------------------------
    // Copyright (c) Microsoft Corporation. All rights reserved.
    // ----------------------------------------------------------------------------
    //
    // Defines the Zumo runtime HTTP server, which delegates to the request handler.
    
    var path = require('path'),
        RequestHandler = require('./request/requesthandler'),
        Request = require('./request/request'),
        Logger = require('./logger'),
        StatusCodes = require('./statuscodes').StatusCodes,
        core = require('./core'),
        tripwire = require('tripwire'),
        Metrics = require('./metrics'),
        ScriptManager = require('./script/scriptmanager'),
        resource = require('./resources'),
        _ = require('underscore'),
        _str = require('underscore.string'),
        express = require('express');
    
    _.mixin(_str.exports());
    
    var logSource = 'Server';
    
    exports.createServer = createServer;
    
    function createServer(options) {
        Logger.initialize(options.logServiceURL, options.logServiceToken);
    
        var configPath = path.join(__dirname, '..', options.dataDirectory || './App_Data', 'config'),
            globalLogger = new Logger(LogLevel[options.logLevel]),
            metrics = new Metrics(globalLogger, parseInt(options.metricsTimeout || 300000, 10)), // Five minutes default
            maxRequestBodySize = (options.maxRequestBodySizeKB || 1024) * 1024,
            authenticationCredentials = getAuthenticationCredentials(options),
            crossDomainWhitelist = getCrossDomainWhitelist(globalLogger);
    
        var scriptManager = new ScriptManager(configPath, options.userConnectionString, options.applicationName, core.parseBoolean(options.dynamicSchemaEnabled), authenticationCredentials, options.ApnsCertificatePassword, options.ApnsCertificateMode, globalLogger, metrics);
        var requestHandler = new RequestHandler(configPath, options.applicationMasterKey, options.applicationSystemKey, options.applicationName, authenticationCredentials, crossDomainWhitelist, options.userConnectionString, options.applicationKey, core.parseBoolean(options.dynamicSchemaEnabled), options.runtimeVersion, options.requestTimeout, scriptManager, globalLogger, metrics, options.logLevel, options.logServiceURL, options.logServiceToken, maxRequestBodySize);
        var app = express();
    
        var server;
        if (options.pfx) {
            server = require('https').createServer({ pfx: options.pfx, passphrase: options.passphrase }, app);
        }
        else {
            server = require('http').createServer(app);
        }
    
        Logger.writer.on('error', function () {
            // ignore failures. we need this handler here to prevent errors
            // from bubbling up to the global exception handler, which would
            // cause the process to be killed 
        });
    
        registerUncaughtExceptionListener(server, options, globalLogger, metrics);
    
        // override the listen function so the server only starts listening
        // once all async initialization is complete
        var originalListen = server.listen;
        server.listen = function () {
            var listenArgs = arguments;
    
            requestHandler.initialize(app, function () {
                scriptManager.runStartupScript(3600000);
                originalListen.apply(server, listenArgs);
            });
        };
    
        return server;
    }
    
    function registerUncaughtExceptionListener(server, options, logger, metrics) {
        var tripwireContext = {};
        var tripwireKeepalive = parseInt(options.tripwireKeepalive, 10) || 1000;
        var processShutdownTimeout = parseInt(options.processShutdownTimeout, 10) || 2000;
    
        // 99.9% of the time async errors will end up here and we assume all async errors belong to user code
        var onUncaughtException = function (e) {
            process.removeAllListeners('uncaughtException');
    
            var exitCode;
            var isTripWireError = false;
            if (tripwireContext === tripwire.getContext()) {
                e = new Error(_.sprintf(resource.tripwireError, tripwireKeepalive));
                exitCode = 2;
                isTripWireError = true;
            }
            else {
                e = e || new Error('The application generated an unspecified exception.');
                exitCode = 1;
            }
    
            logGlobalException(e, isTripWireError, logger);
    
            // flush any pending global log operations
            Logger.flush();
    
            // Wait a short period of time to allow any other logger instances a chance
            // to flush themselves (based on their flush timeouts).
            setTimeout(function () {
                process.exit(exitCode);
            }, processShutdownTimeout);
        };
    
        process.on('uncaughtException', onUncaughtException);
    
        function resetTripwire() {
            tripwire.resetTripwire(tripwireKeepalive * 2, tripwireContext);
        }
    
        resetTripwire();
        var tripwireInterval = setInterval(resetTripwire, tripwireKeepalive);
    
        server.on('close', function () {
            tripwire.clearTripwire();
            clearInterval(tripwireInterval);
            process.removeListener('uncaughtException', onUncaughtException);
        });
    }
    
    function logGlobalException(e, isTripWireError, logger) {
        if (!isTripWireError && core.isRuntimeError(e)) {
            logger.error(logSource, e);
        } else {
            var userScriptSource = core.parseUserScriptError(e);
            var stackPrefix = userScriptSource ? '' : 'An unhandled exception occurred. ';
            var stack = e.stack ? stackPrefix + e.stack : '';
    
            var errMsg = stack || e.message || e.toString();
            logger.logUser(userScriptSource, 'error', errMsg);
        }
    }
    
    function getAuthenticationCredentials(options) {
        var result = {
            microsoftaccount: {
                clientId: process.env.WLClientId,
                clientSecret: process.env.WLClientSecret || options.wLClientSecret,
                packageSid: process.env.WLPackageSid || options.wLPackageSid
            },
            facebook: {
                appId: process.env.AUTH_FACEBOOK_APPID,
                appSecret: process.env.AUTH_FACEBOOK_SECRET
            },
            twitter: {
                consumerKey: process.env.AUTH_TWITTER_APPID,
                consumerSecret: process.env.AUTH_TWITTER_SECRET
            },
            google: {
                clientId: process.env.AUTH_GOOGLE_APPID,
                clientSecret: process.env.AUTH_GOOGLE_SECRET,
                gcmApiKey: process.env.GCM_API_KEY
            }
        };
    
        result.microsoftaccount.enabled = isProviderEnabled(result.microsoftaccount.clientId, result.microsoftaccount.clientSecret);
        result.facebook.enabled = isProviderEnabled(result.facebook.appId, result.facebook.appSecret);
        result.twitter.enabled = isProviderEnabled(result.twitter.consumerKey, result.twitter.consumerSecret);
        result.google.enabled = isProviderEnabled(result.google.clientId, result.google.clientSecret);
    
        return result;
    
        // a certain auth credential provider is enabled if all required fields are non empty strings
        function isProviderEnabled(id, secret) {
            if (typeof (id) !== "string" || id.length === 0) {
                return false;
            }
            if (typeof (secret) !== "string" || secret.length === 0) {
                return false;
            }
            return true;
        }
    }
    
    function getCrossDomainWhitelist(logger) {
        var serializedValue = process.env.CrossDomainWhitelist;
        if (serializedValue) {
            try {
                return JSON.parse(serializedValue);
            } catch (ex) {
                ex.message += "; Attempted JSON value: " + serializedValue;
                logger.error(logSource, ex);
            }
        }
    
        return null;
    }
    

    As you can see in the call from App.js to the function createServer(options), the options are actually Process.Env, the environment settings. So all the configuration settings you can do in the Azure Mobile Services UI like the DynamicSchemaEnabled are just persisted to environment variables. If a value is not set yet (like in the above case the authentication credentials), the enviroment variable does not exist yet.

    In the above code you see that the options parameter (containing a hashtable with all environment variable settings) and Process.Env are used mixed. A good example is the function getAuthenticationCredentials(options), the options (Process.Env) are passed in as a parameter, but it still reads the settings directly from Process.Env.

    If you look at the code above, a lot of things are initialized based on the enviroment variables. If environment variables are changed through the Azure Mobile Services Web UI, the process must be restarted to pick-up the new environment settings an reinitialize the application. I did not investigate this further yet.

    If you look at the above code the following roughly happening:

    1. A lot of node.js modules are loaded
    2. The server is instantiated
    3. Log service is initialized
    4. Global variables like authentication configuration and the cross domain white list (CORS) are set
    5. The scriptmanager (wires the api, table and scheduler scripts)
    6. The requesthandler is initialized, this handles the request that come in and uses the scriptmanager for redirecting to api, table or scheduler scripts
    7. The Express() web server system is started
    8. Top-level Exception handling is configured
    9. When all (async) initialization is completed the Express server starts listening to requests and we are in business

    From there on a lot of stuff is happening. Too much to describe in this blog post, and too much for me to understand in detail. I think it is better to have a look for yourself, check out https://documented.azure-mobile.net/api/dir. Let me know what you think of this:-)

  • Azure Mobile Services: available modules

    Azure Mobile Services has documented a set of objects available in your Azure Mobile Services server side scripts at their documentation page Mobile Services server script reference. Although the documented list is a nice list of objects for the common things you want to do, it will be sooner than later that you will look for more functionality to be included in your script, especially with the new provided feature that you can now create your custom API’s. If you use GIT it is now possible to add any NPM module (node package manager module, say the NuGet of the node world), but why include a module if it is already available out of the box. And you can only use GIT with Azure Mobile Services if you are an administrator on your Azure Mobile Service, not if you are a co-administrator (will be solved in the future).

    Until now I did some trial and error experimentation to test if a certain module was available. This is easiest to do as follows:

     

    Create a custom API, for example named experiment.

    In this API use the following code:

    exports.get = function (request, response) {
        var module = "nonexistingmodule";
        var m = require(module);
        response.send(200, "Module '%s' found.", module);
    };

    You can now test your service with the following request in your browser: https://yourservice.azure-mobile.net/api/experiment

    If you get the result:

    {"code":500,"error":"Error: Internal Server Error"}

    you know that the module does not exist. In your logs you will find the following error:

    Error in script '/api/experiment.json'. Error: Cannot find module 'nonexistingmodule' [external code] at
    C:\DWASFiles\Sites\yourservice\VirtualDirectory0\site\wwwroot\App_Data\config\scripts\api\experiment.js:3:13
    [external code]

    If you require an existing (undocumented) module like the OAuth module in the following code, you will get success as a result:

    exports.get = function (request, response) {
        var module = "oauth";
        var m = require(module);
        response.send(200, "Module '" + module + "' found.");
    };

    If we look at the standard node.js documentation we see an extensive list of modules that can be used from your code. If we look at the list of files available in the Azure Mobile Services platform as documented in the blog post Azure Mobile Services: what files does it consist of? we see a folder node_modules with many more modules are used to build the Azure Mobile Services functionality on, but that can also be utilized from your server side node script code:

    • apn - An interface to the Apple Push Notification service for Node.js.
    • dpush - Send push notifications to Android devices using GCM.
    • mpns - A Node.js interface to the Microsoft Push Notification Service (MPNS) for Windows Phone.
    • wns - Send push notifications to Windows 8 devices using WNS.
    • pusher - Node library for the Pusher server API (see also: http://pusher.com/)
    • azure - Windows Azure Client Library for node.
    • express - Sinatra inspired web development framework.
    • oauth - Library for interacting with OAuth 1.0, 1.0A, 2 and Echo. Provides simplified client access and allows for construction of more complex apis and OAuth providers.
    • request - Simplified HTTP request client.
    • sax - An evented streaming XML parser in JavaScript
    • sendgrid - A NodeJS implementation of the SendGrid Api.
    • sqlserver – In node repository known as msnodesql - Microsoft Driver for Node.js for SQL Server.
    • tripwire - Break out from scripts blocking node.js event loop.
    • underscore - JavaScript's functional programming helper library.
    • underscore.string - String manipulation extensions for Underscore.js javascript library.
    • xml2js - Simple XML to JavaScript object converter.
    • xmlbuilder - An XML builder for node.js.

    As stated before, many of these modules are used to provide the functionality of Azure Mobile Services platform, and in general should not be used directly. On the other hand, I needed OAuth badly to authenticate to the new v1.1 services of Twitter, and was very happy that a require('oauth') and a few lines of code did the job.

    Based on the above modules and a lot of code in the other javascript files in the Azure Mobile Services platform a set of global objects is provided that can be used from your server side node.js script code. In future blog posts I will go into more details with respect to how this code is built-up, all starting at the node.js express entry point app.js.

  • Azure Mobile Services: what files does it consist of?

    Azure Mobile Services is a platform that provides a small set of functionality consisting of authentication, custom data tables, custom API’s, scheduling scripts and push notifications to be used as the back-end of a mobile application or if you want, any application or web site. As described in my previous post Azure Mobile Services: lessons learned the documentation on what can be used in the custom scripts is a bit minimalistic. The list below of all files the complete Azure Mobile Services platform consists of ca shed some light on what is available in the platform. In following posts I will provide more detailed information on what we can conclude from this list of files.

    Below are the available files as available in the Azure Mobile Services platform. The bold files are files that describe your data model, api scripts, scheduler scripts and table scripts. Those are the files you configure/construct to provide the “configuration”/implementation of you mobile service.

    The files are located in a folder like C:\DWASFiles\Sites\youreservice\VirtualDirectory0\site\wwwroot.

    One file is missing in the list below and that is the event log file C:\DWASFiles\Sites\youreservice\VirtualDirectory0\site\LogFiles\eventlog.xml where your messages written with for example console.log() and exception catched by the system are written.

    NOTA BENE: the Azure Mobile Services system is a system that is under full development, new releases may change the list of files.

    • ./app.js
    • ./App_Data/config/datamodel.json
    • ./App_Data/config/scripts/api/youreapi.js
    • ./App_Data/config/scripts/api/youreapi.json
    • ./App_Data/config/scripts/scheduler/placeholder
    • ./App_Data/config/scripts/scheduler/youresheduler.js
    • ./App_Data/config/scripts/shared/placeholder
    • ./App_Data/config/scripts/table/placeholder
    • ./App_Data/config/scripts/table/yourtable.insert.js
    • ./App_Data/config/scripts/table/yourtable.update.js
    • ./App_Data/config/scripts/table/yourtable.delete.js
    • ./App_Data/config/scripts/table/yourtable.read.js
    • ./node_modules/apn/index.js
    • ./node_modules/apn/lib/connection.js
    • ./node_modules/apn/lib/device.js
    • ./node_modules/apn/lib/errors.js
    • ./node_modules/apn/lib/feedback.js
    • ./node_modules/apn/lib/notification.js
    • ./node_modules/apn/lib/util.js
    • ./node_modules/apn/node_modules/q/package.json
    • ./node_modules/apn/node_modules/q/q.js
    • ./node_modules/apn/package.json
    • ./node_modules/azure/lib/azure.js
    • ./node_modules/azure/lib/cli/blobUtils.js
    • ./node_modules/azure/lib/cli/cacheUtils.js
    • ./node_modules/azure/lib/cli/callbackAggregator.js
    • ./node_modules/azure/lib/cli/cert.js
    • ./node_modules/azure/lib/cli/channel.js
    • ./node_modules/azure/lib/cli/cli.js
    • ./node_modules/azure/lib/cli/commands/account.js
    • ./node_modules/azure/lib/cli/commands/config.js
    • ./node_modules/azure/lib/cli/commands/deployment.js
    • ./node_modules/azure/lib/cli/commands/deployment_.js
    • ./node_modules/azure/lib/cli/commands/help.js
    • ./node_modules/azure/lib/cli/commands/log.js
    • ./node_modules/azure/lib/cli/commands/log_.js
    • ./node_modules/azure/lib/cli/commands/repository.js
    • ./node_modules/azure/lib/cli/commands/repository_.js
    • ./node_modules/azure/lib/cli/commands/service.js
    • ./node_modules/azure/lib/cli/commands/site.js
    • ./node_modules/azure/lib/cli/commands/site_.js
    • ./node_modules/azure/lib/cli/commands/vm.js
    • ./node_modules/azure/lib/cli/common.js
    • ./node_modules/azure/lib/cli/constants.js
    • ./node_modules/azure/lib/cli/generate-psm1-utils.js
    • ./node_modules/azure/lib/cli/generate-psm1.js
    • ./node_modules/azure/lib/cli/iaas/blobserviceex.js
    • ./node_modules/azure/lib/cli/iaas/deleteImage.js
    • ./node_modules/azure/lib/cli/iaas/image.js
    • ./node_modules/azure/lib/cli/iaas/upload/blobInfo.js
    • ./node_modules/azure/lib/cli/iaas/upload/bufferStream.js
    • ./node_modules/azure/lib/cli/iaas/upload/intSet.js
    • ./node_modules/azure/lib/cli/iaas/upload/jobTracker.js
    • ./node_modules/azure/lib/cli/iaas/upload/pageBlob.js
    • ./node_modules/azure/lib/cli/iaas/upload/streamMerger.js
    • ./node_modules/azure/lib/cli/iaas/upload/uploadVMImage.js
    • ./node_modules/azure/lib/cli/iaas/upload/vhdTools.js
    • ./node_modules/azure/lib/cli/keyFiles.js
    • ./node_modules/azure/lib/cli/patch-winston.js
    • ./node_modules/azure/lib/cli/templates/node/iisnode.yml
    • ./node_modules/azure/lib/cli/utils.js
    • ./node_modules/azure/lib/diagnostics/logger.js
    • ./node_modules/azure/lib/http/webresource.js
    • ./node_modules/azure/lib/serviceruntime/fileinputchannel.js
    • ./node_modules/azure/lib/serviceruntime/goalstatedeserializer.js
    • ./node_modules/azure/lib/serviceruntime/namedpipeinputchannel.js
    • ./node_modules/azure/lib/serviceruntime/namedpipeoutputchannel.js
    • ./node_modules/azure/lib/serviceruntime/protocol1runtimeclient.js
    • ./node_modules/azure/lib/serviceruntime/protocol1runtimecurrentstateclient.js
    • ./node_modules/azure/lib/serviceruntime/protocol1runtimegoalstateclient.js
    • ./node_modules/azure/lib/serviceruntime/roleenvironment.js
    • ./node_modules/azure/lib/serviceruntime/runtimekernel.js
    • ./node_modules/azure/lib/serviceruntime/runtimeversionmanager.js
    • ./node_modules/azure/lib/serviceruntime/runtimeversionprotocolclient.js
    • ./node_modules/azure/lib/serviceruntime/xmlcurrentstateserializer.js
    • ./node_modules/azure/lib/serviceruntime/xmlgoalstatedeserializer.js
    • ./node_modules/azure/lib/serviceruntime/xmlroleenvironmentdatadeserializer.js
    • ./node_modules/azure/lib/services/blob/blobservice.js
    • ./node_modules/azure/lib/services/blob/hmacsha256sign.js
    • ./node_modules/azure/lib/services/blob/models/blobresult.js
    • ./node_modules/azure/lib/services/blob/models/blocklistresult.js
    • ./node_modules/azure/lib/services/blob/models/containeraclresult.js
    • ./node_modules/azure/lib/services/blob/models/containerresult.js
    • ./node_modules/azure/lib/services/blob/models/leaseresult.js
    • ./node_modules/azure/lib/services/blob/models/listblobsresultcontinuation.js
    • ./node_modules/azure/lib/services/blob/models/listcontainersresultcontinuation.js
    • ./node_modules/azure/lib/services/blob/models/servicepropertiesresult.js
    • ./node_modules/azure/lib/services/blob/sharedaccesssignature.js
    • ./node_modules/azure/lib/services/blob/sharedkey.js
    • ./node_modules/azure/lib/services/blob/sharedkeylite.js
    • ./node_modules/azure/lib/services/core/connectionstringparser.js
    • ./node_modules/azure/lib/services/core/exponentialretrypolicyfilter.js
    • ./node_modules/azure/lib/services/core/linearretrypolicyfilter.js
    • ./node_modules/azure/lib/services/core/servicebusserviceclient.js
    • ./node_modules/azure/lib/services/core/servicebussettings.js
    • ./node_modules/azure/lib/services/core/serviceclient.js
    • ./node_modules/azure/lib/services/core/servicemanagementclient.js
    • ./node_modules/azure/lib/services/core/servicemanagementsettings.js
    • ./node_modules/azure/lib/services/core/servicesettings.js
    • ./node_modules/azure/lib/services/core/storageserviceclient.js
    • ./node_modules/azure/lib/services/core/storageservicesettings.js
    • ./node_modules/azure/lib/services/queue/models/listqueuesresultcontinuation.js
    • ./node_modules/azure/lib/services/queue/models/queuemessageresult.js
    • ./node_modules/azure/lib/services/queue/models/queueresult.js
    • ./node_modules/azure/lib/services/queue/models/servicepropertiesresult.js
    • ./node_modules/azure/lib/services/queue/queueservice.js
    • ./node_modules/azure/lib/services/serviceBus/models/acstokenresult.js
    • ./node_modules/azure/lib/services/serviceBus/models/queuemessageresult.js
    • ./node_modules/azure/lib/services/serviceBus/models/queueresult.js
    • ./node_modules/azure/lib/services/serviceBus/models/ruleresult.js
    • ./node_modules/azure/lib/services/serviceBus/models/subscriptionresult.js
    • ./node_modules/azure/lib/services/serviceBus/models/topicresult.js
    • ./node_modules/azure/lib/services/serviceBus/servicebusservice.js
    • ./node_modules/azure/lib/services/serviceBus/wrap.js
    • ./node_modules/azure/lib/services/serviceBus/wrapservice.js
    • ./node_modules/azure/lib/services/serviceBus/wraptokenmanager.js
    • ./node_modules/azure/lib/services/serviceManagement/models/roleparser.js
    • ./node_modules/azure/lib/services/serviceManagement/models/roleschema.json
    • ./node_modules/azure/lib/services/serviceManagement/models/servicemanagementserialize.js
    • ./node_modules/azure/lib/services/serviceManagement/servicemanagementservice.js
    • ./node_modules/azure/lib/services/table/batchserviceclient.js
    • ./node_modules/azure/lib/services/table/models/entityresult.js
    • ./node_modules/azure/lib/services/table/models/queryentitiesresultcontinuation.js
    • ./node_modules/azure/lib/services/table/models/querytablesresultcontinuation.js
    • ./node_modules/azure/lib/services/table/models/servicepropertiesresult.js
    • ./node_modules/azure/lib/services/table/models/tableresult.js
    • ./node_modules/azure/lib/services/table/sharedkeylitetable.js
    • ./node_modules/azure/lib/services/table/sharedkeytable.js
    • ./node_modules/azure/lib/services/table/tablequery.js
    • ./node_modules/azure/lib/services/table/tableservice.js
    • ./node_modules/azure/lib/util/atomhandler.js
    • ./node_modules/azure/lib/util/certificates/der.js
    • ./node_modules/azure/lib/util/certificates/pkcs.js
    • ./node_modules/azure/lib/util/constants.js
    • ./node_modules/azure/lib/util/iso8061date.js
    • ./node_modules/azure/lib/util/js2xml.js
    • ./node_modules/azure/lib/util/rfc1123date.js
    • ./node_modules/azure/lib/util/util.js
    • ./node_modules/azure/lib/util/validate.js
    • ./node_modules/azure/LICENSE.txt
    • ./node_modules/azure/node_modules/async/index.js
    • ./node_modules/azure/node_modules/async/lib/async.js
    • ./node_modules/azure/node_modules/async/LICENSE
    • ./node_modules/azure/node_modules/async/package.json
    • ./node_modules/azure/node_modules/azure/lib/azure.js
    • ./node_modules/azure/node_modules/azure/lib/diagnostics/logger.js
    • ./node_modules/azure/node_modules/azure/lib/http/webresource.js
    • ./node_modules/azure/node_modules/azure/lib/serviceruntime/fileinputchannel.js
    • ./node_modules/azure/node_modules/azure/lib/serviceruntime/goalstatedeserializer.js
    • ./node_modules/azure/node_modules/azure/lib/serviceruntime/namedpipeinputchannel.js
    • ./node_modules/azure/node_modules/azure/lib/serviceruntime/namedpipeoutputchannel.js
    • ./node_modules/azure/node_modules/azure/lib/serviceruntime/protocol1runtimeclient.js
    • ./node_modules/azure/node_modules/azure/lib/serviceruntime/protocol1runtimecurrentstateclient.js
    • ./node_modules/azure/node_modules/azure/lib/serviceruntime/protocol1runtimegoalstateclient.js
    • ./node_modules/azure/node_modules/azure/lib/serviceruntime/roleenvironment.js
    • ./node_modules/azure/node_modules/azure/lib/serviceruntime/runtimekernel.js
    • ./node_modules/azure/node_modules/azure/lib/serviceruntime/runtimeversionmanager.js
    • ./node_modules/azure/node_modules/azure/lib/serviceruntime/runtimeversionprotocolclient.js
    • ./node_modules/azure/node_modules/azure/lib/serviceruntime/xmlcurrentstateserializer.js
    • ./node_modules/azure/node_modules/azure/lib/serviceruntime/xmlgoalstatedeserializer.js
    • ./node_modules/azure/node_modules/azure/lib/serviceruntime/xmlroleenvironmentdatadeserializer.js
    • ./node_modules/azure/node_modules/azure/lib/services/blob/blobservice.js
    • ./node_modules/azure/node_modules/azure/lib/services/blob/internal/sharedaccesssignature.js
    • ./node_modules/azure/node_modules/azure/lib/services/blob/internal/sharedkey.js
    • ./node_modules/azure/node_modules/azure/lib/services/blob/internal/sharedkeylite.js
    • ./node_modules/azure/node_modules/azure/lib/services/blob/models/blobresult.js
    • ./node_modules/azure/node_modules/azure/lib/services/blob/models/blocklistresult.js
    • ./node_modules/azure/node_modules/azure/lib/services/blob/models/containeraclresult.js
    • ./node_modules/azure/node_modules/azure/lib/services/blob/models/containerresult.js
    • ./node_modules/azure/node_modules/azure/lib/services/blob/models/leaseresult.js
    • ./node_modules/azure/node_modules/azure/lib/services/blob/models/listblobsresultcontinuation.js
    • ./node_modules/azure/node_modules/azure/lib/services/blob/models/listcontainersresultcontinuation.js
    • ./node_modules/azure/node_modules/azure/lib/services/blob/models/servicepropertiesresult.js
    • ./node_modules/azure/node_modules/azure/lib/services/core/connectionstringparser.js
    • ./node_modules/azure/node_modules/azure/lib/services/core/exponentialretrypolicyfilter.js
    • ./node_modules/azure/node_modules/azure/lib/services/core/hmacsha256sign.js
    • ./node_modules/azure/node_modules/azure/lib/services/core/linearretrypolicyfilter.js
    • ./node_modules/azure/node_modules/azure/lib/services/core/servicebusserviceclient.js
    • ./node_modules/azure/node_modules/azure/lib/services/core/servicebussettings.js
    • ./node_modules/azure/node_modules/azure/lib/services/core/serviceclient.js
    • ./node_modules/azure/node_modules/azure/lib/services/core/servicemanagementclient.js
    • ./node_modules/azure/node_modules/azure/lib/services/core/servicemanagementsettings.js
    • ./node_modules/azure/node_modules/azure/lib/services/core/servicesettings.js
    • ./node_modules/azure/node_modules/azure/lib/services/core/sqlserviceclient.js
    • ./node_modules/azure/node_modules/azure/lib/services/core/storageserviceclient.js
    • ./node_modules/azure/node_modules/azure/lib/services/core/storageservicesettings.js
    • ./node_modules/azure/node_modules/azure/lib/services/queue/models/listqueuesresultcontinuation.js
    • ./node_modules/azure/node_modules/azure/lib/services/queue/models/queuemessageresult.js
    • ./node_modules/azure/node_modules/azure/lib/services/queue/models/queueresult.js
    • ./node_modules/azure/node_modules/azure/lib/services/queue/models/servicepropertiesresult.js
    • ./node_modules/azure/node_modules/azure/lib/services/queue/queueservice.js
    • ./node_modules/azure/node_modules/azure/lib/services/serviceBus/apnsservice.js
    • ./node_modules/azure/node_modules/azure/lib/services/serviceBus/gcmservice.js
    • ./node_modules/azure/node_modules/azure/lib/services/serviceBus/internal/sharedaccesssignature.js
    • ./node_modules/azure/node_modules/azure/lib/services/serviceBus/internal/wrap.js
    • ./node_modules/azure/node_modules/azure/lib/services/serviceBus/internal/wraptokenmanager.js
    • ./node_modules/azure/node_modules/azure/lib/services/serviceBus/models/acstokenresult.js
    • ./node_modules/azure/node_modules/azure/lib/services/serviceBus/models/notificationhubresult.js
    • ./node_modules/azure/node_modules/azure/lib/services/serviceBus/models/queuemessageresult.js
    • ./node_modules/azure/node_modules/azure/lib/services/serviceBus/models/queueresult.js
    • ./node_modules/azure/node_modules/azure/lib/services/serviceBus/models/registrationresult.js
    • ./node_modules/azure/node_modules/azure/lib/services/serviceBus/models/resourceresult.js
    • ./node_modules/azure/node_modules/azure/lib/services/serviceBus/models/ruleresult.js
    • ./node_modules/azure/node_modules/azure/lib/services/serviceBus/models/subscriptionresult.js
    • ./node_modules/azure/node_modules/azure/lib/services/serviceBus/models/topicresult.js
    • ./node_modules/azure/node_modules/azure/lib/services/serviceBus/notificationhubservice.js
    • ./node_modules/azure/node_modules/azure/lib/services/serviceBus/servicebusservice.js
    • ./node_modules/azure/node_modules/azure/lib/services/serviceBus/servicebusservicebase.js
    • ./node_modules/azure/node_modules/azure/lib/services/serviceBus/wnsservice.js
    • ./node_modules/azure/node_modules/azure/lib/services/serviceBus/wrapservice.js
    • ./node_modules/azure/node_modules/azure/lib/services/serviceManagement/hdinsightservice.js
    • ./node_modules/azure/node_modules/azure/lib/services/serviceManagement/models/roleparser.js
    • ./node_modules/azure/node_modules/azure/lib/services/serviceManagement/models/roleschema.json
    • ./node_modules/azure/node_modules/azure/lib/services/serviceManagement/models/servicemanagementserialize.js
    • ./node_modules/azure/node_modules/azure/lib/services/serviceManagement/servicebusmanagementservice.js
    • ./node_modules/azure/node_modules/azure/lib/services/serviceManagement/servicemanagementservice.js
    • ./node_modules/azure/node_modules/azure/lib/services/serviceManagement/sqlmanagementservice.js
    • ./node_modules/azure/node_modules/azure/lib/services/sqlAzure/models/databaseresult.js
    • ./node_modules/azure/node_modules/azure/lib/services/sqlAzure/sqlserveracs.js
    • ./node_modules/azure/node_modules/azure/lib/services/sqlAzure/sqlservice.js
    • ./node_modules/azure/node_modules/azure/lib/services/table/batchserviceclient.js
    • ./node_modules/azure/node_modules/azure/lib/services/table/internal/sharedkeylitetable.js
    • ./node_modules/azure/node_modules/azure/lib/services/table/internal/sharedkeytable.js
    • ./node_modules/azure/node_modules/azure/lib/services/table/models/entityresult.js
    • ./node_modules/azure/node_modules/azure/lib/services/table/models/listresult.js
    • ./node_modules/azure/node_modules/azure/lib/services/table/models/queryentitiesresultcontinuation.js
    • ./node_modules/azure/node_modules/azure/lib/services/table/models/querytablesresultcontinuation.js
    • ./node_modules/azure/node_modules/azure/lib/services/table/models/servicepropertiesresult.js
    • ./node_modules/azure/node_modules/azure/lib/services/table/models/tableresult.js
    • ./node_modules/azure/node_modules/azure/lib/services/table/tablequery.js
    • ./node_modules/azure/node_modules/azure/lib/services/table/tableservice.js
    • ./node_modules/azure/node_modules/azure/lib/util/atomhandler.js
    • ./node_modules/azure/node_modules/azure/lib/util/constants.js
    • ./node_modules/azure/node_modules/azure/lib/util/date.js
    • ./node_modules/azure/node_modules/azure/lib/util/edmtype.js
    • ./node_modules/azure/node_modules/azure/lib/util/iso8061date.js
    • ./node_modules/azure/node_modules/azure/lib/util/js2xml.js
    • ./node_modules/azure/node_modules/azure/lib/util/odatahandler.js
    • ./node_modules/azure/node_modules/azure/lib/util/rfc1123date.js
    • ./node_modules/azure/node_modules/azure/lib/util/util.js
    • ./node_modules/azure/node_modules/azure/lib/util/validate.js
    • ./node_modules/azure/node_modules/azure/LICENSE.txt
    • ./node_modules/azure/node_modules/azure/node_modules/wns/lib/wns.js
    • ./node_modules/azure/node_modules/azure/node_modules/wns/LICENSE.txt
    • ./node_modules/azure/node_modules/azure/node_modules/wns/package.json
    • ./node_modules/azure/node_modules/azure/node_modules/xml2js/lib/xml2js.js
    • ./node_modules/azure/node_modules/azure/node_modules/xml2js/LICENSE
    • ./node_modules/azure/node_modules/azure/node_modules/xml2js/node_modules/sax/lib/sax.js
    • ./node_modules/azure/node_modules/azure/node_modules/xml2js/node_modules/sax/LICENSE
    • ./node_modules/azure/node_modules/azure/node_modules/xml2js/node_modules/sax/package.json
    • ./node_modules/azure/node_modules/azure/node_modules/xml2js/package.json
    • ./node_modules/azure/node_modules/azure/package.json
    • ./node_modules/azure/node_modules/colors/colors.js
    • ./node_modules/azure/node_modules/colors/MIT-LICENSE.txt
    • ./node_modules/azure/node_modules/colors/package.json
    • ./node_modules/azure/node_modules/commander/index.js
    • ./node_modules/azure/node_modules/commander/lib/commander.js
    • ./node_modules/azure/node_modules/commander/node_modules/keypress/index.js
    • ./node_modules/azure/node_modules/commander/node_modules/keypress/package.json
    • ./node_modules/azure/node_modules/commander/package.json
    • ./node_modules/azure/node_modules/dateformat/lib/dateformat.js
    • ./node_modules/azure/node_modules/dateformat/package.json
    • ./node_modules/azure/node_modules/easy-table/lib/table.js
    • ./node_modules/azure/node_modules/easy-table/package.json
    • ./node_modules/azure/node_modules/eyes/lib/eyes.js
    • ./node_modules/azure/node_modules/eyes/LICENSE
    • ./node_modules/azure/node_modules/eyes/package.json
    • ./node_modules/azure/node_modules/log/index.js
    • ./node_modules/azure/node_modules/log/lib/log.js
    • ./node_modules/azure/node_modules/log/package.json
    • ./node_modules/azure/node_modules/mime/LICENSE
    • ./node_modules/azure/node_modules/mime/mime.js
    • ./node_modules/azure/node_modules/mime/package.json
    • ./node_modules/azure/node_modules/mime/types/mime.types
    • ./node_modules/azure/node_modules/mime/types/node.types
    • ./node_modules/azure/node_modules/node-uuid/LICENSE.md
    • ./node_modules/azure/node_modules/node-uuid/package.json
    • ./node_modules/azure/node_modules/node-uuid/uuid.js
    • ./node_modules/azure/node_modules/qs/component.json
    • ./node_modules/azure/node_modules/qs/index.js
    • ./node_modules/azure/node_modules/qs/lib/head.js
    • ./node_modules/azure/node_modules/qs/lib/querystring.js
    • ./node_modules/azure/node_modules/qs/lib/tail.js
    • ./node_modules/azure/node_modules/qs/package.json
    • ./node_modules/azure/node_modules/qs/querystring.js
    • ./node_modules/azure/node_modules/request/aws.js
    • ./node_modules/azure/node_modules/request/forever.js
    • ./node_modules/azure/node_modules/request/LICENSE
    • ./node_modules/azure/node_modules/request/main.js
    • ./node_modules/azure/node_modules/request/node_modules/form-data/lib/form_data.js
    • ./node_modules/azure/node_modules/request/node_modules/form-data/node_modules/async/index.js
    • ./node_modules/azure/node_modules/request/node_modules/form-data/node_modules/async/lib/async.js
    • ./node_modules/azure/node_modules/request/node_modules/form-data/node_modules/async/LICENSE
    • ./node_modules/azure/node_modules/request/node_modules/form-data/node_modules/async/package.json
    • ./node_modules/azure/node_modules/request/node_modules/form-data/node_modules/combined-stream/lib/combined_stream.js
    • ./node_modules/azure/node_modules/request/node_modules/form-data/node_modules/combined-stream/License
    • ./node_modules/azure/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/lib/delayed_stream.js
    • ./node_modules/azure/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/License
    • ./node_modules/azure/node_modules/request/node_modules/form-data/node_modules/combined-stream/node_modules/delayed-stream/package.json
    • ./node_modules/azure/node_modules/request/node_modules/form-data/node_modules/combined-stream/package.json
    • ./node_modules/azure/node_modules/request/node_modules/form-data/package.json
    • ./node_modules/azure/node_modules/request/node_modules/mime/LICENSE
    • ./node_modules/azure/node_modules/request/node_modules/mime/mime.js
    • ./node_modules/azure/node_modules/request/node_modules/mime/package.json
    • ./node_modules/azure/node_modules/request/node_modules/mime/types/mime.types
    • ./node_modules/azure/node_modules/request/node_modules/mime/types/node.types
    • ./node_modules/azure/node_modules/request/oauth.js
    • ./node_modules/azure/node_modules/request/package.json
    • ./node_modules/azure/node_modules/request/tunnel.js
    • ./node_modules/azure/node_modules/request/uuid.js
    • ./node_modules/azure/node_modules/request/vendor/cookie/index.js
    • ./node_modules/azure/node_modules/request/vendor/cookie/jar.js
    • ./node_modules/azure/node_modules/sax/lib/sax.js
    • ./node_modules/azure/node_modules/sax/LICENSE
    • ./node_modules/azure/node_modules/sax/package.json
    • ./node_modules/azure/node_modules/streamline/AUTHORS
    • ./node_modules/azure/node_modules/streamline/deps/narcissus/lib/decompiler.js
    • ./node_modules/azure/node_modules/streamline/deps/narcissus/lib/definitions.js
    • ./node_modules/azure/node_modules/streamline/deps/narcissus/lib/jsbrowser.js
    • ./node_modules/azure/node_modules/streamline/deps/narcissus/lib/jsdecomp.js
    • ./node_modules/azure/node_modules/streamline/deps/narcissus/lib/jsdefs.js
    • ./node_modules/azure/node_modules/streamline/deps/narcissus/lib/jsexec.js
    • ./node_modules/azure/node_modules/streamline/deps/narcissus/lib/jslex.js
    • ./node_modules/azure/node_modules/streamline/deps/narcissus/lib/jsparse.js
    • ./node_modules/azure/node_modules/streamline/deps/narcissus/lib/lexer.js
    • ./node_modules/azure/node_modules/streamline/deps/narcissus/lib/parser.js
    • ./node_modules/azure/node_modules/streamline/deps/narcissus/LICENSE
    • ./node_modules/azure/node_modules/streamline/deps/narcissus/main.js
    • ./node_modules/azure/node_modules/streamline/deps/narcissus/package.json
    • ./node_modules/azure/node_modules/streamline/deps/narcissus/xfail/narcissus-failures.txt
    • ./node_modules/azure/node_modules/streamline/deps/narcissus/xfail/narcissus-slow.txt
    • ./node_modules/azure/node_modules/streamline/lib/callbacks/format.js
    • ./node_modules/azure/node_modules/streamline/lib/callbacks/require-stub.js
    • ./node_modules/azure/node_modules/streamline/lib/callbacks/runtime.js
    • ./node_modules/azure/node_modules/streamline/lib/callbacks/transform.js
    • ./node_modules/azure/node_modules/streamline/lib/compile.js
    • ./node_modules/azure/node_modules/streamline/lib/compiler/command.js
    • ./node_modules/azure/node_modules/streamline/lib/compiler/compile--fibers.js
    • ./node_modules/azure/node_modules/streamline/lib/compiler/compile.js
    • ./node_modules/azure/node_modules/streamline/lib/compiler/compile_.js
    • ./node_modules/azure/node_modules/streamline/lib/compiler/index.js
    • ./node_modules/azure/node_modules/streamline/lib/compiler/register.js
    • ./node_modules/azure/node_modules/streamline/lib/fibers/runtime.js
    • ./node_modules/azure/node_modules/streamline/lib/fibers/transform.js
    • ./node_modules/azure/node_modules/streamline/lib/fibers/walker.js
    • ./node_modules/azure/node_modules/streamline/lib/globals.js
    • ./node_modules/azure/node_modules/streamline/lib/index.js
    • ./node_modules/azure/node_modules/streamline/lib/register.js
    • ./node_modules/azure/node_modules/streamline/lib/require/client/require.js
    • ./node_modules/azure/node_modules/streamline/lib/require/server/depend.js
    • ./node_modules/azure/node_modules/streamline/lib/require/server/require.js
    • ./node_modules/azure/node_modules/streamline/lib/streams/client/streams--fibers.js
    • ./node_modules/azure/node_modules/streamline/lib/streams/client/streams.js
    • ./node_modules/azure/node_modules/streamline/lib/streams/client/streams_.js
    • ./node_modules/azure/node_modules/streamline/lib/streams/jsonRequest.js
    • ./node_modules/azure/node_modules/streamline/lib/streams/readers.js
    • ./node_modules/azure/node_modules/streamline/lib/streams/server/httpHelper.js
    • ./node_modules/azure/node_modules/streamline/lib/streams/server/streams.js
    • ./node_modules/azure/node_modules/streamline/lib/streams/streams.js
    • ./node_modules/azure/node_modules/streamline/lib/tools/docTool.js
    • ./node_modules/azure/node_modules/streamline/lib/transform.js
    • ./node_modules/azure/node_modules/streamline/lib/util/flows--fibers.js
    • ./node_modules/azure/node_modules/streamline/lib/util/flows.js
    • ./node_modules/azure/node_modules/streamline/lib/util/flows_.js
    • ./node_modules/azure/node_modules/streamline/lib/util/future.js
    • ./node_modules/azure/node_modules/streamline/lib/util/index.js
    • ./node_modules/azure/node_modules/streamline/lib/util/url.js
    • ./node_modules/azure/node_modules/streamline/lib/util/uuid.js
    • ./node_modules/azure/node_modules/streamline/module.js
    • ./node_modules/azure/node_modules/streamline/package.json
    • ./node_modules/azure/node_modules/tunnel/index.js
    • ./node_modules/azure/node_modules/tunnel/lib/tunnel.js
    • ./node_modules/azure/node_modules/tunnel/package.json
    • ./node_modules/azure/node_modules/underscore/index.js
    • ./node_modules/azure/node_modules/underscore/LICENSE
    • ./node_modules/azure/node_modules/underscore/package.json
    • ./node_modules/azure/node_modules/underscore/underscore.js
    • ./node_modules/azure/node_modules/underscore.string/lib/underscore.string.js
    • ./node_modules/azure/node_modules/underscore.string/package.json
    • ./node_modules/azure/node_modules/validator/index.js
    • ./node_modules/azure/node_modules/validator/lib/defaultError.js
    • ./node_modules/azure/node_modules/validator/lib/entities.js
    • ./node_modules/azure/node_modules/validator/lib/filter.js
    • ./node_modules/azure/node_modules/validator/lib/index.js
    • ./node_modules/azure/node_modules/validator/lib/validator.js
    • ./node_modules/azure/node_modules/validator/lib/validators.js
    • ./node_modules/azure/node_modules/validator/lib/xss.js
    • ./node_modules/azure/node_modules/validator/LICENSE
    • ./node_modules/azure/node_modules/validator/package.json
    • ./node_modules/azure/node_modules/validator/validator.js
    • ./node_modules/azure/node_modules/winston/lib/winston/common.js
    • ./node_modules/azure/node_modules/winston/lib/winston/config/cli-config.js
    • ./node_modules/azure/node_modules/winston/lib/winston/config/npm-config.js
    • ./node_modules/azure/node_modules/winston/lib/winston/config/syslog-config.js
    • ./node_modules/azure/node_modules/winston/lib/winston/config.js
    • ./node_modules/azure/node_modules/winston/lib/winston/container.js
    • ./node_modules/azure/node_modules/winston/lib/winston/exception.js
    • ./node_modules/azure/node_modules/winston/lib/winston/logger.js
    • ./node_modules/azure/node_modules/winston/lib/winston/transports/console.js
    • ./node_modules/azure/node_modules/winston/lib/winston/transports/file.js
    • ./node_modules/azure/node_modules/winston/lib/winston/transports/http.js
    • ./node_modules/azure/node_modules/winston/lib/winston/transports/transport.js
    • ./node_modules/azure/node_modules/winston/lib/winston/transports/webhook.js
    • ./node_modules/azure/node_modules/winston/lib/winston/transports.js
    • ./node_modules/azure/node_modules/winston/lib/winston.js
    • ./node_modules/azure/node_modules/winston/LICENSE
    • ./node_modules/azure/node_modules/winston/node_modules/cycle/cycle.js
    • ./node_modules/azure/node_modules/winston/node_modules/cycle/package.json
    • ./node_modules/azure/node_modules/winston/node_modules/pkginfo/lib/pkginfo.js
    • ./node_modules/azure/node_modules/winston/node_modules/pkginfo/package.json
    • ./node_modules/azure/node_modules/winston/node_modules/request/aws.js
    • ./node_modules/azure/node_modules/winston/node_modules/request/aws2.js
    • ./node_modules/azure/node_modules/winston/node_modules/request/forever.js
    • ./node_modules/azure/node_modules/winston/node_modules/request/LICENSE
    • ./node_modules/azure/node_modules/winston/node_modules/request/main.js
    • ./node_modules/azure/node_modules/winston/node_modules/request/mimetypes.js
    • ./node_modules/azure/node_modules/winston/node_modules/request/oauth.js
    • ./node_modules/azure/node_modules/winston/node_modules/request/package.json
    • ./node_modules/azure/node_modules/winston/node_modules/request/tunnel.js
    • ./node_modules/azure/node_modules/winston/node_modules/request/uuid.js
    • ./node_modules/azure/node_modules/winston/node_modules/request/vendor/cookie/index.js
    • ./node_modules/azure/node_modules/winston/node_modules/request/vendor/cookie/jar.js
    • ./node_modules/azure/node_modules/winston/node_modules/stack-trace/lib/stack-trace.js
    • ./node_modules/azure/node_modules/winston/node_modules/stack-trace/License
    • ./node_modules/azure/node_modules/winston/node_modules/stack-trace/package.json
    • ./node_modules/azure/node_modules/winston/package.json
    • ./node_modules/azure/node_modules/xml2js/lib/xml2js.js
    • ./node_modules/azure/node_modules/xml2js/LICENSE
    • ./node_modules/azure/node_modules/xml2js/package.json
    • ./node_modules/azure/node_modules/xmlbuilder/lib/index.js
    • ./node_modules/azure/node_modules/xmlbuilder/lib/XMLBuilder.js
    • ./node_modules/azure/node_modules/xmlbuilder/lib/XMLFragment.js
    • ./node_modules/azure/node_modules/xmlbuilder/package.json
    • ./node_modules/azure/package.json
    • ./node_modules/dpush/lib/dpush.js
    • ./node_modules/dpush/LICENSE.txt
    • ./node_modules/dpush/package.json
    • ./node_modules/express/.npmignore
    • ./node_modules/express/.travis.yml
    • ./node_modules/express/bin/express
    • ./node_modules/express/History.md
    • ./node_modules/express/index.js
    • ./node_modules/express/lib/application.js
    • ./node_modules/express/lib/express.js
    • ./node_modules/express/lib/middleware.js
    • ./node_modules/express/lib/request.js
    • ./node_modules/express/lib/response.js
    • ./node_modules/express/lib/router/index.js
    • ./node_modules/express/lib/router/route.js
    • ./node_modules/express/lib/utils.js
    • ./node_modules/express/lib/view.js
    • ./node_modules/express/LICENSE
    • ./node_modules/express/Makefile
    • ./node_modules/express/node_modules/buffer-crc32/.npmignore
    • ./node_modules/express/node_modules/buffer-crc32/.travis.yml
    • ./node_modules/express/node_modules/buffer-crc32/index.js
    • ./node_modules/express/node_modules/buffer-crc32/package.json
    • ./node_modules/express/node_modules/buffer-crc32/README.md
    • ./node_modules/express/node_modules/buffer-crc32/tests/crc.test.js
    • ./node_modules/express/node_modules/commander/.npmignore
    • ./node_modules/express/node_modules/commander/.travis.yml
    • ./node_modules/express/node_modules/commander/History.md
    • ./node_modules/express/node_modules/commander/index.js
    • ./node_modules/express/node_modules/commander/lib/commander.js
    • ./node_modules/express/node_modules/commander/Makefile
    • ./node_modules/express/node_modules/commander/package.json
    • ./node_modules/express/node_modules/commander/Readme.md
    • ./node_modules/express/node_modules/connect/.npmignore
    • ./node_modules/express/node_modules/connect/.travis.yml
    • ./node_modules/express/node_modules/connect/index.js
    • ./node_modules/express/node_modules/connect/lib/cache.js
    • ./node_modules/express/node_modules/connect/lib/connect.js
    • ./node_modules/express/node_modules/connect/lib/index.js
    • ./node_modules/express/node_modules/connect/lib/middleware/basicAuth.js
    • ./node_modules/express/node_modules/connect/lib/middleware/bodyParser.js
    • ./node_modules/express/node_modules/connect/lib/middleware/compress.js
    • ./node_modules/express/node_modules/connect/lib/middleware/cookieParser.js
    • ./node_modules/express/node_modules/connect/lib/middleware/cookieSession.js
    • ./node_modules/express/node_modules/connect/lib/middleware/csrf.js
    • ./node_modules/express/node_modules/connect/lib/middleware/directory.js
    • ./node_modules/express/node_modules/connect/lib/middleware/errorHandler.js
    • ./node_modules/express/node_modules/connect/lib/middleware/favicon.js
    • ./node_modules/express/node_modules/connect/lib/middleware/json.js
    • ./node_modules/express/node_modules/connect/lib/middleware/limit.js
    • ./node_modules/express/node_modules/connect/lib/middleware/logger.js
    • ./node_modules/express/node_modules/connect/lib/middleware/methodOverride.js
    • ./node_modules/express/node_modules/connect/lib/middleware/multipart.js
    • ./node_modules/express/node_modules/connect/lib/middleware/query.js
    • ./node_modules/express/node_modules/connect/lib/middleware/responseTime.js
    • ./node_modules/express/node_modules/connect/lib/middleware/session/cookie.js
    • ./node_modules/express/node_modules/connect/lib/middleware/session/memory.js
    • ./node_modules/express/node_modules/connect/lib/middleware/session/session.js
    • ./node_modules/express/node_modules/connect/lib/middleware/session/store.js
    • ./node_modules/express/node_modules/connect/lib/middleware/session.js
    • ./node_modules/express/node_modules/connect/lib/middleware/static.js
    • ./node_modules/express/node_modules/connect/lib/middleware/staticCache.js
    • ./node_modules/express/node_modules/connect/lib/middleware/timeout.js
    • ./node_modules/express/node_modules/connect/lib/middleware/urlencoded.js
    • ./node_modules/express/node_modules/connect/lib/middleware/vhost.js
    • ./node_modules/express/node_modules/connect/lib/patch.js
    • ./node_modules/express/node_modules/connect/lib/proto.js
    • ./node_modules/express/node_modules/connect/lib/public/directory.html
    • ./node_modules/express/node_modules/connect/lib/public/error.html
    • ./node_modules/express/node_modules/connect/lib/public/favicon.ico
    • ./node_modules/express/node_modules/connect/lib/public/icons/page.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_add.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_attach.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_code.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_copy.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_delete.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_edit.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_error.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_excel.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_find.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_gear.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_go.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_green.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_key.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_lightning.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_link.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_paintbrush.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_paste.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_red.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_refresh.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_save.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_acrobat.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_actionscript.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_add.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_c.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_camera.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_cd.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_code.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_code_red.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_coldfusion.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_compressed.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_copy.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_cplusplus.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_csharp.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_cup.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_database.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_delete.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_dvd.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_edit.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_error.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_excel.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_find.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_flash.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_freehand.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_gear.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_get.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_go.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_h.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_horizontal.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_key.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_lightning.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_link.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_magnify.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_medal.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_office.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_paint.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_paintbrush.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_paste.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_php.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_picture.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_powerpoint.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_put.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_ruby.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_stack.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_star.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_swoosh.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_text.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_text_width.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_tux.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_vector.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_visualstudio.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_width.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_word.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_world.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_wrench.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_white_zip.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_word.png
    • ./node_modules/express/node_modules/connect/lib/public/icons/page_world.png
    • ./node_modules/express/node_modules/connect/lib/public/style.css
    • ./node_modules/express/node_modules/connect/lib/utils.js
    • ./node_modules/express/node_modules/connect/LICENSE
    • ./node_modules/express/node_modules/connect/node_modules/bytes/.npmignore
    • ./node_modules/express/node_modules/connect/node_modules/bytes/component.json
    • ./node_modules/express/node_modules/connect/node_modules/bytes/History.md
    • ./node_modules/express/node_modules/connect/node_modules/bytes/index.js
    • ./node_modules/express/node_modules/connect/node_modules/bytes/Makefile
    • ./node_modules/express/node_modules/connect/node_modules/bytes/package.json
    • ./node_modules/express/node_modules/connect/node_modules/bytes/Readme.md
    • ./node_modules/express/node_modules/connect/node_modules/formidable/.npmignore
    • ./node_modules/express/node_modules/connect/node_modules/formidable/.travis.yml
    • ./node_modules/express/node_modules/connect/node_modules/formidable/benchmark/bench-multipart-parser.js
    • ./node_modules/express/node_modules/connect/node_modules/formidable/example/json.js
    • ./node_modules/express/node_modules/connect/node_modules/formidable/example/post.js
    • ./node_modules/express/node_modules/connect/node_modules/formidable/example/upload.js
    • ./node_modules/express/node_modules/connect/node_modules/formidable/index.js
    • ./node_modules/express/node_modules/connect/node_modules/formidable/lib/file.js
    • ./node_modules/express/node_modules/connect/node_modules/formidable/lib/incoming_form.js
    • ./node_modules/express/node_modules/connect/node_modules/formidable/lib/index.js
    • ./node_modules/express/node_modules/connect/node_modules/formidable/lib/json_parser.js
    • ./node_modules/express/node_modules/connect/node_modules/formidable/lib/multipart_parser.js
    • ./node_modules/express/node_modules/connect/node_modules/formidable/lib/octet_parser.js
    • ./node_modules/express/node_modules/connect/node_modules/formidable/lib/querystring_parser.js
    • ./node_modules/express/node_modules/connect/node_modules/formidable/LICENSE
    • ./node_modules/express/node_modules/connect/node_modules/formidable/package.json
    • ./node_modules/express/node_modules/connect/node_modules/formidable/Readme.md
    • ./node_modules/express/node_modules/connect/node_modules/formidable/test/common.js
    • ./node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/file/beta-sticker-1.png
    • ./node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/file/binaryfile.tar.gz
    • ./node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/file/blank.gif
    • ./node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/file/funkyfilename.txt
    • ./node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/file/menu_separator.png
    • ./node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/file/plain.txt
    • ./node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/http/special-chars-in-filename/info.md
    • ./node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/js/encoding.js
    • ./node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/js/misc.js
    • ./node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/js/no-filename.js
    • ./node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/js/preamble.js
    • ./node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/js/special-chars-in-filename.js
    • ./node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/js/workarounds.js
    • ./node_modules/express/node_modules/connect/node_modules/formidable/test/fixture/multipart.js
    • ./node_modules/express/node_modules/connect/node_modules/formidable/test/integration/test-fixtures.js
    • ./node_modules/express/node_modules/connect/node_modules/formidable/test/integration/test-json.js
    • ./node_modules/express/node_modules/connect/node_modules/formidable/test/integration/test-octet-stream.js
    • ./node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/common.js
    • ./node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/integration/test-multipart-parser.js
    • ./node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/simple/test-file.js
    • ./node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/simple/test-incoming-form.js
    • ./node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/simple/test-multipart-parser.js
    • ./node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/simple/test-querystring-parser.js
    • ./node_modules/express/node_modules/connect/node_modules/formidable/test/legacy/system/test-multi-video-upload.js
    • ./node_modules/express/node_modules/connect/node_modules/formidable/test/run.js
    • ./node_modules/express/node_modules/connect/node_modules/formidable/test/standalone/test-connection-aborted.js
    • ./node_modules/express/node_modules/connect/node_modules/formidable/test/standalone/test-content-transfer-encoding.js
    • ./node_modules/express/node_modules/connect/node_modules/formidable/test/standalone/test-issue-46.js
    • ./node_modules/express/node_modules/connect/node_modules/formidable/test/tools/base64.html
    • ./node_modules/express/node_modules/connect/node_modules/formidable/test/unit/test-file.js
    • ./node_modules/express/node_modules/connect/node_modules/formidable/test/unit/test-incoming-form.js
    • ./node_modules/express/node_modules/connect/node_modules/formidable/tool/record.js
    • ./node_modules/express/node_modules/connect/node_modules/pause/.npmignore
    • ./node_modules/express/node_modules/connect/node_modules/pause/History.md
    • ./node_modules/express/node_modules/connect/node_modules/pause/index.js
    • ./node_modules/express/node_modules/connect/node_modules/pause/Makefile
    • ./node_modules/express/node_modules/connect/node_modules/pause/package.json
    • ./node_modules/express/node_modules/connect/node_modules/pause/Readme.md
    • ./node_modules/express/node_modules/connect/node_modules/qs/.gitmodules
    • ./node_modules/express/node_modules/connect/node_modules/qs/.npmignore
    • ./node_modules/express/node_modules/connect/node_modules/qs/index.js
    • ./node_modules/express/node_modules/connect/node_modules/qs/package.json
    • ./node_modules/express/node_modules/connect/node_modules/qs/Readme.md
    • ./node_modules/express/node_modules/connect/package.json
    • ./node_modules/express/node_modules/connect/test.js
    • ./node_modules/express/node_modules/cookie/.npmignore
    • ./node_modules/express/node_modules/cookie/.travis.yml
    • ./node_modules/express/node_modules/cookie/index.js
    • ./node_modules/express/node_modules/cookie/package.json
    • ./node_modules/express/node_modules/cookie/README.md
    • ./node_modules/express/node_modules/cookie/test/mocha.opts
    • ./node_modules/express/node_modules/cookie/test/parse.js
    • ./node_modules/express/node_modules/cookie/test/serialize.js
    • ./node_modules/express/node_modules/cookie-signature/.npmignore
    • ./node_modules/express/node_modules/cookie-signature/History.md
    • ./node_modules/express/node_modules/cookie-signature/index.js
    • ./node_modules/express/node_modules/cookie-signature/Makefile
    • ./node_modules/express/node_modules/cookie-signature/package.json
    • ./node_modules/express/node_modules/cookie-signature/Readme.md
    • ./node_modules/express/node_modules/debug/.npmignore
    • ./node_modules/express/node_modules/debug/component.json
    • ./node_modules/express/node_modules/debug/debug.js
    • ./node_modules/express/node_modules/debug/example/app.js
    • ./node_modules/express/node_modules/debug/example/browser.html
    • ./node_modules/express/node_modules/debug/example/wildcards.js
    • ./node_modules/express/node_modules/debug/example/worker.js
    • ./node_modules/express/node_modules/debug/History.md
    • ./node_modules/express/node_modules/debug/index.js
    • ./node_modules/express/node_modules/debug/lib/debug.js
    • ./node_modules/express/node_modules/debug/package.json
    • ./node_modules/express/node_modules/debug/Readme.md
    • ./node_modules/express/node_modules/fresh/.npmignore
    • ./node_modules/express/node_modules/fresh/index.js
    • ./node_modules/express/node_modules/fresh/Makefile
    • ./node_modules/express/node_modules/fresh/package.json
    • ./node_modules/express/node_modules/fresh/Readme.md
    • ./node_modules/express/node_modules/methods/index.js
    • ./node_modules/express/node_modules/methods/package.json
    • ./node_modules/express/node_modules/mkdirp/.npmignore
    • ./node_modules/express/node_modules/mkdirp/.travis.yml
    • ./node_modules/express/node_modules/mkdirp/examples/pow.js
    • ./node_modules/express/node_modules/mkdirp/index.js
    • ./node_modules/express/node_modules/mkdirp/LICENSE
    • ./node_modules/express/node_modules/mkdirp/package.json
    • ./node_modules/express/node_modules/mkdirp/README.markdown
    • ./node_modules/express/node_modules/mkdirp/test/chmod.js
    • ./node_modules/express/node_modules/mkdirp/test/clobber.js
    • ./node_modules/express/node_modules/mkdirp/test/mkdirp.js
    • ./node_modules/express/node_modules/mkdirp/test/perm.js
    • ./node_modules/express/node_modules/mkdirp/test/perm_sync.js
    • ./node_modules/express/node_modules/mkdirp/test/race.js
    • ./node_modules/express/node_modules/mkdirp/test/rel.js
    • ./node_modules/express/node_modules/mkdirp/test/return.js
    • ./node_modules/express/node_modules/mkdirp/test/return_sync.js
    • ./node_modules/express/node_modules/mkdirp/test/root.js
    • ./node_modules/express/node_modules/mkdirp/test/sync.js
    • ./node_modules/express/node_modules/mkdirp/test/umask.js
    • ./node_modules/express/node_modules/mkdirp/test/umask_sync.js
    • ./node_modules/express/node_modules/range-parser/.npmignore
    • ./node_modules/express/node_modules/range-parser/History.md
    • ./node_modules/express/node_modules/range-parser/index.js
    • ./node_modules/express/node_modules/range-parser/Makefile
    • ./node_modules/express/node_modules/range-parser/package.json
    • ./node_modules/express/node_modules/range-parser/Readme.md
    • ./node_modules/express/node_modules/send/.npmignore
    • ./node_modules/express/node_modules/send/History.md
    • ./node_modules/express/node_modules/send/index.js
    • ./node_modules/express/node_modules/send/lib/send.js
    • ./node_modules/express/node_modules/send/lib/utils.js
    • ./node_modules/express/node_modules/send/Makefile
    • ./node_modules/express/node_modules/send/node_modules/mime/LICENSE
    • ./node_modules/express/node_modules/send/node_modules/mime/mime.js
    • ./node_modules/express/node_modules/send/node_modules/mime/package.json
    • ./node_modules/express/node_modules/send/node_modules/mime/README.md
    • ./node_modules/express/node_modules/send/node_modules/mime/test.js
    • ./node_modules/express/node_modules/send/node_modules/mime/types/mime.types
    • ./node_modules/express/node_modules/send/node_modules/mime/types/node.types
    • ./node_modules/express/node_modules/send/package.json
    • ./node_modules/express/node_modules/send/Readme.md
    • ./node_modules/express/package.json
    • ./node_modules/express/Readme.md
    • ./node_modules/mpns/lib/mpns.js
    • ./node_modules/mpns/package.json
    • ./node_modules/oauth/index.js
    • ./node_modules/oauth/lib/oauth.js
    • ./node_modules/oauth/lib/oauth2.js
    • ./node_modules/oauth/lib/sha1.js
    • ./node_modules/oauth/lib/_utils.js
    • ./node_modules/oauth/LICENSE
    • ./node_modules/oauth/package.json
    • ./node_modules/pusher/index.js
    • ./node_modules/pusher/lib/pusher.js
    • ./node_modules/pusher/node_modules/request/aws.js
    • ./node_modules/pusher/node_modules/request/aws2.js
    • ./node_modules/pusher/node_modules/request/forever.js
    • ./node_modules/pusher/node_modules/request/LICENSE
    • ./node_modules/pusher/node_modules/request/main.js
    • ./node_modules/pusher/node_modules/request/mimetypes.js
    • ./node_modules/pusher/node_modules/request/oauth.js
    • ./node_modules/pusher/node_modules/request/package.json
    • ./node_modules/pusher/node_modules/request/tunnel.js
    • ./node_modules/pusher/node_modules/request/uuid.js
    • ./node_modules/pusher/node_modules/request/vendor/cookie/index.js
    • ./node_modules/pusher/node_modules/request/vendor/cookie/jar.js
    • ./node_modules/pusher/package.json
    • ./node_modules/request/forever.js
    • ./node_modules/request/LICENSE
    • ./node_modules/request/main.js
    • ./node_modules/request/mimetypes.js
    • ./node_modules/request/oauth.js
    • ./node_modules/request/package.json
    • ./node_modules/request/uuid.js
    • ./node_modules/request/vendor/cookie/index.js
    • ./node_modules/request/vendor/cookie/jar.js
    • ./node_modules/sax/lib/sax.js
    • ./node_modules/sax/LICENSE
    • ./node_modules/sax/package.json
    • ./node_modules/sendgrid/index.js
    • ./node_modules/sendgrid/lib/email.js
    • ./node_modules/sendgrid/lib/file_handler.js
    • ./node_modules/sendgrid/lib/sendgrid.js
    • ./node_modules/sendgrid/lib/smtpapi_headers.js
    • ./node_modules/sendgrid/lib/validation.js
    • ./node_modules/sendgrid/MIT.LICENSE
    • ./node_modules/sendgrid/node_modules/mime/LICENSE
    • ./node_modules/sendgrid/node_modules/mime/mime.js
    • ./node_modules/sendgrid/node_modules/mime/package.json
    • ./node_modules/sendgrid/node_modules/mime/types/mime.types
    • ./node_modules/sendgrid/node_modules/mime/types/node.types
    • ./node_modules/sendgrid/node_modules/nodemailer/lib/engines/sendmail.js
    • ./node_modules/sendgrid/node_modules/nodemailer/lib/engines/ses.js
    • ./node_modules/sendgrid/node_modules/nodemailer/lib/engines/smtp.js
    • ./node_modules/sendgrid/node_modules/nodemailer/lib/engines/stub.js
    • ./node_modules/sendgrid/node_modules/nodemailer/lib/helpers.js
    • ./node_modules/sendgrid/node_modules/nodemailer/lib/nodemailer.js
    • ./node_modules/sendgrid/node_modules/nodemailer/lib/transport.js
    • ./node_modules/sendgrid/node_modules/nodemailer/lib/wellknown.js
    • ./node_modules/sendgrid/node_modules/nodemailer/lib/xoauth.js
    • ./node_modules/sendgrid/node_modules/nodemailer/LICENSE
    • ./node_modules/sendgrid/node_modules/nodemailer/node_modules/mailcomposer/lib/dkim.js
    • ./node_modules/sendgrid/node_modules/nodemailer/node_modules/mailcomposer/lib/mailcomposer.js
    • ./node_modules/sendgrid/node_modules/nodemailer/node_modules/mailcomposer/lib/punycode.js
    • ./node_modules/sendgrid/node_modules/nodemailer/node_modules/mailcomposer/lib/urlfetch.js
    • ./node_modules/sendgrid/node_modules/nodemailer/node_modules/mailcomposer/LICENSE
    • ./node_modules/sendgrid/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/content-types.js
    • ./node_modules/sendgrid/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/index.js
    • ./node_modules/sendgrid/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/LICENSE
    • ./node_modules/sendgrid/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/mime-functions.js
    • ./node_modules/sendgrid/node_modules/nodemailer/node_modules/mailcomposer/node_modules/mimelib-noiconv/package.json
    • ./node_modules/sendgrid/node_modules/nodemailer/node_modules/mailcomposer/package.json
    • ./node_modules/sendgrid/node_modules/nodemailer/node_modules/simplesmtp/index.js
    • ./node_modules/sendgrid/node_modules/nodemailer/node_modules/simplesmtp/lib/client.js
    • ./node_modules/sendgrid/node_modules/nodemailer/node_modules/simplesmtp/lib/pool.js
    • ./node_modules/sendgrid/node_modules/nodemailer/node_modules/simplesmtp/lib/server.js
    • ./node_modules/sendgrid/node_modules/nodemailer/node_modules/simplesmtp/lib/starttls.js
    • ./node_modules/sendgrid/node_modules/nodemailer/node_modules/simplesmtp/LICENSE
    • ./node_modules/sendgrid/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/cert/cert.pem
    • ./node_modules/sendgrid/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/cert/key.pem
    • ./node_modules/sendgrid/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/lib/mockup.js
    • ./node_modules/sendgrid/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/lib/rai.js
    • ./node_modules/sendgrid/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/lib/starttls.js
    • ./node_modules/sendgrid/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/LICENSE
    • ./node_modules/sendgrid/node_modules/nodemailer/node_modules/simplesmtp/node_modules/rai/package.json
    • ./node_modules/sendgrid/node_modules/nodemailer/node_modules/simplesmtp/package.json
    • ./node_modules/sendgrid/node_modules/nodemailer/package.json
    • ./node_modules/sendgrid/node_modules/step/lib/step.js
    • ./node_modules/sendgrid/node_modules/step/package.json
    • ./node_modules/sendgrid/node_modules/underscore/index.js
    • ./node_modules/sendgrid/node_modules/underscore/LICENSE
    • ./node_modules/sendgrid/node_modules/underscore/package.json
    • ./node_modules/sendgrid/node_modules/underscore/underscore.js
    • ./node_modules/sendgrid/package.json
    • ./node_modules/sqlserver/lib/sql.js
    • ./node_modules/sqlserver/lib/sqlserver.native.js
    • ./node_modules/sqlserver/lib/sqlserver.node
    • ./node_modules/sqlserver/package.json
    • ./node_modules/tripwire/lib/native/windows/x86/tripwire.node
    • ./node_modules/tripwire/lib/tripwire.js
    • ./node_modules/tripwire/LICENSE.txt
    • ./node_modules/tripwire/package.json
    • ./node_modules/underscore/LICENSE
    • ./node_modules/underscore/package.json
    • ./node_modules/underscore/underscore.js
    • ./node_modules/underscore.string/lib/underscore.string.js
    • ./node_modules/underscore.string/package.json
    • ./node_modules/wns/lib/wns.js
    • ./node_modules/wns/LICENSE.txt
    • ./node_modules/wns/package.json
    • ./node_modules/xml2js/lib/xml2js.js
    • ./node_modules/xml2js/LICENSE
    • ./node_modules/xml2js/node_modules/sax/lib/sax.js
    • ./node_modules/xml2js/node_modules/sax/LICENSE
    • ./node_modules/xml2js/node_modules/sax/package.json
    • ./node_modules/xml2js/package.json
    • ./node_modules/xmlbuilder/lib/index.js
    • ./node_modules/xmlbuilder/lib/XMLBuilder.js
    • ./node_modules/xmlbuilder/lib/XMLFragment.js
    • ./node_modules/xmlbuilder/package.json
    • ./runtime/core.js
    • ./runtime/filehelpers.js
    • ./runtime/jsonwebtoken.js
    • ./runtime/logger.js
    • ./runtime/logwriter.js
    • ./runtime/metrics.js
    • ./runtime/query/expressions.js
    • ./runtime/query/expressionvisitor.js
    • ./runtime/query/queryparser.js
    • ./runtime/request/authentication/facebook.js
    • ./runtime/request/authentication/google.js
    • ./runtime/request/authentication/microsoftaccount.js
    • ./runtime/request/authentication/twitter.js
    • ./runtime/request/dataoperation.js
    • ./runtime/request/datapipeline.js
    • ./runtime/request/html/corshelper.js
    • ./runtime/request/html/crossdomainhandler.js
    • ./runtime/request/html/templates/crossdomainbridge.html
    • ./runtime/request/html/templates/loginviaiframe.html
    • ./runtime/request/html/templates/loginviaiframereceiver.html
    • ./runtime/request/html/templates/loginviapostmessage.html
    • ./runtime/request/html/templating.js
    • ./runtime/request/loginhandler.js
    • ./runtime/request/middleware/allowHandler.js
    • ./runtime/request/middleware/authenticate.js
    • ./runtime/request/middleware/authorize.js
    • ./runtime/request/middleware/bodyParser.js
    • ./runtime/request/middleware/errorHandler.js
    • ./runtime/request/middleware/requestLimit.js
    • ./runtime/request/request.js
    • ./runtime/request/requesthandler.js
    • ./runtime/request/schedulerhandler.js
    • ./runtime/request/statushandler.js
    • ./runtime/request/tablehandler.js
    • ./runtime/resources.js
    • ./runtime/script/apibuilder.js
    • ./runtime/script/metadata.js
    • ./runtime/script/push/notify-apns.js
    • ./runtime/script/push/notify-gcm.js
    • ./runtime/script/push/notify-mpns.js
    • ./runtime/script/push/notify-wns.js
    • ./runtime/script/push/notify.js
    • ./runtime/script/scriptcache.js
    • ./runtime/script/scripterror.js
    • ./runtime/script/scriptloader.js
    • ./runtime/script/scriptmanager.js
    • ./runtime/script/scriptstate.js
    • ./runtime/script/sqladapter.js
    • ./runtime/script/table.js
    • ./runtime/server.js
    • ./runtime/statuscodes.js
    • ./runtime/storage/sqlbooleanizer.js
    • ./runtime/storage/sqlformatter.js
    • ./runtime/storage/sqlhelpers.js
    • ./runtime/storage/storage.js
    • ./runtime/Zumo.Node.js
    • ./static/client/MobileServices.Web-1.0.0.js
    • ./static/client/MobileServices.Web-1.0.0.min.js
    • ./static/default.htm
    • ./static/robots.txt
    • ./Web.config
  • Azure Mobile Services: lessons learned

    When I first started using Azure Mobile Services I thought of it as a nice way to:

    • authenticate my users - login using Twitter, Google, Facebook, Windows Live
    • create tables, and use the client code to create the columns in the table because that is not possible in the Azure Mobile Services UI
    • run some Javascript code on the table crud actions (Insert, Update, Delete, Read)
    • schedule a Javascript to run any 15 or more minutes

    I had no idea of the magic that was happening inside…

    • where is the data stored? Is it a kind of big table, are relationships between tables possible?
    • those Javascripts on the table crud actions, is that interpreted, what is that exactly?

    After working for some time with Azure Mobile Services I became a lot wiser:

    • Those tables are just normal tables in an Azure SQL Server 2012
    • Creating the table columns through client code sucks, at least from my Javascript code, because the columns are deducted from the sent JSON data, and a datetime field is sent as string in JSON, so a string type column is created instead of a datetime column
    • You can connect with SQL Management Studio to the Azure SQL Server, and although you can’t manage your columns through the SQL Management Studio UI, it is possible to just run SQL scripts to drop and create tables and indices
    • When you create a table through SQL script, add the table with the same name in the Azure Mobile Services UI to hook it up and be able to access the table through the provided abstraction layer
    • You can also go to the SQL Database through the Azure Mobile Services UI, and from there get in a web based SQL management studio where you can create columns and manage your data
    • The table crud scripts and the scheduler scripts are full blown node.js scripts, introducing a lot of power with great performance
    • The web based script editor is really powerful, I do most of my editing currently in the editor which has syntax highlighting and code completing. While editing the code JsHint is used for script validation.
    • The documentation on Azure Mobile Services is… suboptimal. It is such a pity that there is no way to comment on it so the community could fill in the missing holes, like which node modules are already loaded, and which modules are available on Azure Mobile Services.

    Soon I was hacking away on Azure Mobile Services, creating my own database tables through script, and abusing the read script of an empty table named query to implement my own set of “services”.

    The latest updates to Azure Mobile Services described in the following posts added some great new features like creating web API’s, use shared code from your scripts, command line tools for managing Azure Mobile Services (upload and download scripts for example), support for node modules and git support:

    In the mean time I rewrote all my “service-like” table scripts to API scripts, which works like a breeze.

    Bad thing with the current state of Azure Mobile Services is that the git support is not working if you are a co-administrator of your Azure subscription, and not and administrator (as in my case). Another bad thing is that Cross Origin Request Sharing (CORS) is not supported for the API yet, so no go yet from the browser client for API’s, which is my case. See http://social.msdn.microsoft.com/Forums/windowsazure/en-US/2b79c5ea-d187-4c2b-823a-3f3e0559829d/known-limitations-for-source-control-and-custom-api-features for more on these and other limitations.

    In his talk at Build 2013 Josh Twist showed that there is a work-around for accessing shared script code from the table scripts as well (another limitation mentioned in the post above). I could not find that code in the Votabl2 code example from the presentation at https://github.com/joshtwist/votabl2, but we can grab it from the presentation when it comes online on Channel9.

    By the way: you can always express your needs and ideas at http://mobileservices.uservoice.com, that’s the place they are listening to (I hope!).

  • JSON Debugger visualizer in Visual Studio 2012

    Recently working a lot with JSON data. Needed a debugger visualizer for JSON. Found one at: http://jsonviewer.codeplex.com/

    Copy contents of the visualizer folder in the zip package to VisualStudioInstallPath\Common7\Packages\Debugger\Visualizers (on my machine this is C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\Packages\Debugger\Visualizers) and working! See http://msdn.microsoft.com/en-us/library/sb2yca43(v=vs.110).aspx for other instalation options.

    SNAGHTML8c38f1dd

    SNAGHTML8c3e0925

  • SharePoint: UI for ordering list items

    SharePoint list items have in the the base Item template a field named Order. This field is not shown by default.

    SharePoint 2007, 2010 and 2013 have a possibility to specify the order in a UI, using the _layouts page:

    {SiteUrl}/_layouts/Reorder.aspx?List={ListId}

    In SharePoint 2010 and 2013 it is possible to add a custom action to a list. It is possible to add a custom action to order list items as follows (SharePoint 2010 description):

    1. Open SharePoint Designer 2010
    2. Navigate to a list
    3. Select Custom Actions > List Item Menu
      image
    4. Fill in the dialog box:
      SNAGHTML100ead33
      SNAGHTML100f1567
    5. Open List Settings > Advanced Settings > Content Types, and set Allow management of content types to No 
    6. On List Settings select Column Orderingimage

    This results in the following UI in the browser:

    image

    Selecting the custom Order Items action (under List Tools > Items) results in:

    image

    You can change your custom action in SharePoint designer. On the list screen in the bottom right corner you can find the custom action:

    image

    We now need to modify the view to include the order by adding the Order field to the view, and sorting on the Order field. Problem is that the Order field is hidden. It is possible to modify the schema of the Order field to set the Hidden attribute to FALSE. If we don’t want to write code to do it and still get the required result it is also possible to modify the view through SharePoint Designer:

    image

    Modify the code of the view:

    image

    This results in:

    image

    Note that if you change the view through the web UI these changes are partly lost. If this is a problem modify the Order field schema for the list.

  • Icons from CDN (content delivery network)

    Sometimes you need an icon in a site, but don’t want to (or can’t) add the icons themselves to the site. A good example is http://jsfiddle.net (a playground for web developers) where you can only edit html, Javascript and css, but can’t add any icons. In my case I need some icons for a custom SharePoint list action on Office365. I could add the icons to a SharePoint picture library, but I don’t want to do that. So after some search I stumbled upon this StackOverflow question. In one of the answers the site the site http://www.iconfinder.com was mentioned, together with a link to a post describing that linking to the icons from their CDN is allowed (if licence permits it):

    https://getsatisfaction.com/iconfinder/topics/direct_linking_to_icons_from_iconfinder

    I love their search UI where you can specify a search term, that you want a transparent background, the size of the icon, and that you want an unlicensed icon.

    image

    To get the CDN url, select the icon, and on the following screen right-click on the icon and select Copy Image Location.

     

    image

    This results in the following url: http://cdn1.iconfinder.com/data/icons/fugue/icon/edit-list-order.png.

  • Google image search: exact size and file type missing

    When I need an icon I use Google search for images, type in the usage for the icon, for example order, and specify an exact size for the icon.

    Until recently…

     

    Google in their infinite wisdom decided to change the image search UI:

    image

    Select Search tools:

    image

    As you can see, no exact size can be specified… you can specify Icon, but no size for the icon.

    After some searching I found this question nicely answered. An the answer is…. add the following to your search terms:

    imagesize:widthxheight

    So search for: order imagesize:16x16

     

    This results in some messed up UI:

    image

    The next step is that I want to specify the type of image. In the new UI I get the following options:

    image

    That’s not what I mean…I want to say gif or png!

     

    If we go to the Google advanced image search page (http://www.google.com/advanced_image_search), we see some other options:

    image

    After some fiddling we extend our search to: order imagesize:16x16 filetype:png

    image

    The Google search UI is modified again!

     

    Happy image searching!

  • Getting SharePoint 2013 dev machine up and running in 5 minutes

    I’m a happy customer of http://www.cloudshare.com, and only days after the release of SharePoint 2013 preview I was able to spin up an instance of SharePoint Server 2013 with the following configuration:

    SharePoint Server 2013 Preview

    Description: OS: Windows Server 2012 RC x64
    Spec: 80 GB HD / 8 GB RAM
    Installed:
    • SharePoint Server 2013 Preview
    • SQL Server 2012 Standard
    • Visual Studio 2012 RC Ultimate Edition
    • SharePoint Designer 2013 Preview
    • Adobe Reader

    The machine works like a breeze, although I already had some SharePoint crashes. But hey, it’s a preview!

    Kudo’s to CloudShare for getting a template machine up and running so fast.

    PS: I’m in no way affiliated to CloudShare, just a happy customer.

  • SharePoint.DesignFactory.ContentFiles 1.4.0.3 - bugfix release, how to update

    Today I released version 1.4.0.3. of SharePoint.DesignFactory.ContentFiles. This is a bugfix release where the following issues are fixed:

    Change Log - SharePoint.DesignFactory.ContentFiles v1.4.0.3
    ===========================================================

    Product Version:

    1.4.0.3
    - Fixed issue: Documentation and Sample.ps1 machine configuration file had missing ';' after first line of configuration (SharePointDeployment = 'ClientObjectModel')
    - Fixed issue: UseClaims flag of machine configuration was not passed correctly, so Claims Authenticated deployment with client object model (Office365 for example) was not working
    - Fixed issue: Custom configurations not working due to missing parameter in Deploy.cmd and Redeploy.cmd
                   See:
    http://myspworld.wordpress.com/2012/06/25/deploy-content-files-to-sharepoint-using-sharepoint-designfactory-contentfiles/ (thanks Amadeu)
    1.4.0.2
    - Fixed issue: Code outside begin block when doing ClientObjectModel deployment
    - Fixed issue: Not all files packaged (fixed by Danny)
    - Fixed issue: Deployment path incorrect (one letter missing)

    1.4.0.1
    - Fixed issue: Mapped folder ABC would also deploy files in unmapped folder ABCD due to startswith() logic.

    1.4.0.0
    - Initial release to general public.

    To upgrade the NuGet package to a new version execute the following steps:

    1. To upgrade your NuGet package following the following steps:
    2. Right-click on solution or project, and select Manage NuGet packages…
    3. In the Manage NuGet Packages screen click left on Updates
      clip_image002
    4. Select the SharePoint.DesignFactory.ContentFiles package and press the Update button
    5. Open from the menu Build the Configuration Manager
    6. Make the project configurations match the solution configurations (always mixed up after uninstall/install or update)
      clip_image004

    This should get you up and running!

  • Facebook makes some of its core libraries open source (C++)

    For Facebook with 900.000.000 users one of the most important things is performance. Core libraries of Facebook are written in C++, and some of these libraries are now open-source on github: https://github.com/facebook/folly. See also the blog post http://herbsutter.com/2012/06/02/facebook-folly-oss-c-libraries/ and the discussions in this post where other C++ libraries open sourced by big companies are mentioned. There is already someone working on getting the libraries to work under Windows and Visual Studio at the fork: https://github.com/jbandela/folly/tree/vc11/.

  • SharePoint.DesignFactory.ContentFiles–building WCM sites

    One of the use cases where we use the SharePoint.DesignFactory.ContentFiles tooling is in building SharePoint Publishing (WCM) solutions for SharePoint 2007, SharePoint 2010 and Office365.

    Publishing solutions are often solutions that have one instance, the publishing site (possibly with subsites), that in most cases need to go through DTAP.

    If you dissect a publishing site, in most case you have the following findings:

    1. The publishing site spans a site collection
    2. The branding of the site is specified in the root site, because:
      • Master pages live in the root site (/_catalogs/masterpage)
      • Page layouts live in the root site (/_catalogs/masterpage)
      • The style library lives in the root site ( /Style Library) and contains images, css, javascript, xslt transformations for your CQWP’s, …
      • Preconfigured web parts live in the root site (/_catalogs/wp)
    3. The root site and subsites contains a document library called Pages (or your language-specific version of it) containing publishing pages using the page layouts and master pages
    4. The site collection contains content types, fields and lists

    When using the SharePoint.DesignFactory.ContentFiles tooling it is very easy to create, test, package and deploy the artifacts that can be uploaded to the SharePoint content database. This can be done in a fast and simple way without the need to create and deploy WSP packages. If we look at the above list of artifacts we can use SharePoint.DesignFactory.ContentFiles for master pages, page layouts, the style library, web part configurations, and initial publishing pages (these are normally made through the SharePoint web UI).

    Some artifacts like content types, fields and lists in the above list can NOT be handled by SharePoint.DesignFactory.ContentFiles, because they can’t be uploaded to the SharePoint content database. The good thing is that these artifacts are the artifacts that don’t change that much in the development of a SharePoint Publishing solution. There are however multiple ways to create these artifacts:

    1. Use paper script: create them manually in each of the environments based on documentation
    2. Automate the creation of the artifacts using (PowerShell) script
    3. Develop a WSP package to create these artifacts

    I’m not a big fan of the third option (see my blog post Thoughts on building deployable and updatable SharePoint solutions). It is a lot of work to create content types, fields and list definitions using all kind of XML files, and it is not allowed to modify these artifacts when in use. I know… SharePoint 2010 has some content type upgrade possibilities, but I think it is just too cumbersome.

    The first option has the problem that content types and fields get ID’s, and that these ID’s must be used by the metadata on for example page layouts. No problem for SharePoint.DesignFactory.ContentFiles, because it supports deploy-time resolving of these ID’s using PowerShell. For example consider the following metadata definition for the page layout contactpage-wcm.aspx.properties.ps1:

    Metadata page layout
    1. # This script must return a hashtable @{ name=value; ... } of field name-value pairs
    2. # for the content file that this script applies to.
    3. # On deployment to SharePoint, these values are written as fields in the corresponding list item (if any)
    4. # Note that fields must exist; they can be updated but not created or deleted.
    5. # This script is called right after the file is deployed to SharePoint.
    6.  
    7. # You can use the script parameters and arbitrary PowerShell code to interact with SharePoint.
    8. # e.g. to calculate properties and values at deployment time.
    9.  
    10. param([string]$SourcePath, [string]$RelativeUrl, $Context)
    11. @{
    12.     "ContentTypeId" = $Context.GetContentTypeID('GeneralPage');
    13.     "MasterPageDescription" = "Cloud Aviator Contact pagelayout (wcm - don't use)";
    14.     "PublishingHidden" = "1";
    15.     "PublishingAssociatedContentType" = $Context.GetAssociatedContentTypeInfo('GeneralPage')
    16. }

    The PowerShell functions GetContentTypeID and GetAssociatedContentTypeInfo can at deploy-time resolve the required information from the server we are deploying to.

    I personally prefer the second option: automate creation through PowerShell, because there are PowerShell scripts available to export content types and fields.

    An example project structure for a typical SharePoint WCM site looks like:

    image

    Note that this project uses DualLayout.

    So if you build Publishing sites using SharePoint, checkout out the completely free SharePoint.DesignFactory.ContentFiles tooling and start flying!

  • SharePoint.DesignFactory.ContentFiles - Installation

    The SharePoint.DesignFactory.ContentFiles tooling can be used to develop, test, package and deploy SharePoint files and metadata that can be uploaded to the SharePoint content database. Use this tooling for developing and packaging your master pages, page layouts, style library files, web part configurations and any file you can think of that can be uploaded to the SharePoint content database. Works on SharePoint 2007 (on SharePoint server), SharePoint 2010 (on SharePoint server or remote) and Office365 (remote).

    Installation is simple. In this post I will show the steps required to install the SharePoint.DesignFactory.ContentFiles on a Visual studio project.

    1. Fire-up Visual Studio 2010 and create a new project (File > New > Project…)
    2. Under Installed Templates select Visual C# > Web
    3. Select the .Net Framework 3.5, then select the ASP.NET Web Application project
      image
    4. Note that the resulting project contains all kind of artifacts that are not relevant in the context of a SharePoint.DesignFactory.ContentFiles project:
      image
    5. If NuGet is not installed yet on your Visual Studio (Tools > Library Package Manager is missing), start the Visual Studio Extension Manager (Tools > Extension Manager…). In the Extension Manager window select the Online Gallery at the left and search for NuGet. Select the NuGet Package Manager and press the Download button to install NuGet. Preferably use NuGet 1.7 or up to use all features available in the SharePoint.DesignFactory.ContentFiles NuGet package.
      image
    6. Right-click on the just created Web Application project and in the context menu select Manage NuGet Packages….
      image
    7. In the Manage NuGet Packages window select Online at the left and search for SharePoint.DesignFactory.ContentFiles. Select the SharePoint.DesignFactory.ContentFiles package and press the Install button.
      image
    8. After installation where a lot of project manipulation magic happens the following message appears. An assembly is installed in the solution folder containing Visual studio Solution Explorer context menu actions that makes working with SharePoint.DesignFactory.ContentFiles even easier. This assembly is magically loaded by a Visual Studio extension called Managed Menu Extension (MME). Although this extension is not required and it is perfectly possible to work without the additional context menu actions, it is advised to install the Managed Menu Extensions (explained in the next step).
      image
    9. Install the Managed Menu Extensions (MME) through the Extension Manager (Tools > Extension Manager…). Select Online Gallery and search for MME.
      image
    10. Visual studio requires a restart for the Managed Menu Extensions to work and the context menu extension for SharePoint.DesignFactory.ContentFiles to work. Close Visual Studio, and reopen Visual Studio with our new solution in one of two ways (First starting Visual Studio and then loading the solution does not load the menu extensions):
      1. By starting the solution through the start menu
        image
      2. By double-clicking the solution file in the explorer
    11. We are done with installation! The project is cleaned up, all unwanted files are removed. You are presented with a readme file explaining some things about the SharePoint.DesignFactory.ContentFiles tooling.
      image

    In a next blog post I will give a tour through a SharePoint.DesignFactory.ContentFiles enabled Visual Studio project.

  • SharePoint.DesignFactory.ContentFiles NuGet package released

    Wouldn’t it be great to edit your SharePoint 2007/2010/Office365 content files like master pages, page layouts, web part files, style library files etc. etc. in Visual Studio, use intellisense, source control and the XSLT debugger, but without the overhead of creating complex xml files, manifest files and WSP packages? Wouldn’t it be great if you could package those file and deploy them through Dev, Test, Acceptation and Production without WSP packages? Now you can!

    Create an ASP.NET Web Application Project, add the SharePoint.DesignFactory.ContentFiles NuGet package and start building!

    SharePoint.DesignFactory.ContentFiles-NuGet 

    See the included documentation for more information. More information will follow on this blog!

  • EULA SharePoint.DesignFactory.ContentFiles

    LICENSE AGREEMENT FOR Macaw SharePoint.DesignFactory.ContentFiles

    IMPORTANT-READ CAREFULLY: This End User License Agreement (this "LICENSE AGREEMENT") contains the terms and conditions regarding your use of the SOFTWARE (as defined below). This LICENSE AGREEMENT contains material limitations to your rights in that regard. You should read this LICENSE AGREEMENT carefully and treat it as valuable property.

    I. This License Agreement.

    Software covered by this LICENSE AGREEMENT. This LICENSE AGREEMENT governs your use of the Macaw SharePoint.DesignFactory.ContentFiles software product(s) enclosed or otherwise accompanied herewith (individually and collectively, the "SOFTWARE"). The term "SOFTWARE" includes, to the extent provided by Macaw Nederland B.V.:
    1. Any revisions, updates and/or upgrades thereto;
    2. Any data, image or executable files, databases, data engines, computer software, or similar items customarily used or distributed with computer software products;
    3. Anything in any form whatsoever intended to be used with or in conjunction with the SOFTWARE; and
    4. Any associated media, documentation.
     
    This LICENSE AGREEMENT is a Legally Binding Agreement between You and Macaw Nederland B.V..
    If you are acting as an agent of a company or another legal person, such as an officer or other employee acting for your employer, then "you" and "your" mean your principal, the entity or other legal person for whom you are acting. However, importantly, even if you are acting as an agent for another, you may still be personally liable for violation of federal and State laws, such as copyright infringement.

    This LICENSE AGREEMENT is a legally binding agreement between you and Macaw Nederland B.V.. You intend to be legally bound to this LICENSE AGREEMENT to the same extent as if Macaw Nederland B.V. and you physically signed this LICENSE AGREEMENT. By installing, copying, or otherwise using the SOFTWARE, you agree to be bound by the terms and conditions contained in this LICENSE AGREEMENT. If you do not agree to all of the terms and conditions contained in this LICENSE AGREEMENT, you may not install or use the SOFTWARE. If, for whatever reason, installation has begun or has been completed, you should cancel installation or un-install the SOFTWARE, as the case may be. (You may click on the "exit" button or its equivalent to immediately abort installation.) If you do not agree to all of these terms and conditions, then you must promptly return the SOFTWARE to the place of business from which you obtained it in accordance with any return policies of such place of business.

    II. YOUR LICENSE TO INSTALL AND TO USE.

    This LICENSE AGREEMENT grants you a free license. The license for this version of the SOFTWARE requires no payment by the user to Macaw or any other party. However, Macaw or another party may require the user to purchase the computer media and pay service charges related to providing the SOFTWARE to the user. Because this license is granted to the user for no cost, the user is not entitled to free technical support from Macaw Nederland B.V..

    You agree that you will not reverse engineer, decompile or disassemble any portion of the SOFTWARE.

    In all cases, you may not use Macaw's name, logo, or trademarks to market your Web Site without the express written consent of Macaw Nederland B.V.; You agree to indemnify, hold harmless, and defend Macaw Nederland B.V., its suppliers and resellers, from and against any claims or lawsuits, including attorney's fees that may arise from the use or distribution of your Web Site; You may use the SOFTWARE only to create Web Sites.

    You may use the SOFTWARE to create and deploy packages on SharePoint Servers in both non-commerncial and commercial projects.

    III. INTELLECTUAL PROPERTY.

    Copyright. You agree that all right, title, and interest in and to the SOFTWARE (including, but not limited to, any images, photographs, animations, video, audio, music, text, and “applets” incorporated into the SOFTWARE), and any copies of the SOFTWARE, and any copyrights and other intellectual properties therein or related thereto are owned exclusively by Macaw Nederland B.V., except to the limited extent that Macaw Nederland B.V.may be the rightful license holder of certain third-party technologies incorporated into the SOFTWARE. The SOFTWARE is protected by copyright laws and international treaty provisions. The SOFTWARE is licensed to you, not sold to you. Macaw Nederland B.V. reserves all rights not otherwise expressly and specifically granted to you in this LICENSE AGREEMENT.


    IV. WARRANTIES AND REMEDIES.

    Macaw Nederland B.V. expressly disclaims any warranty for the software, documentation and anything else provided by Macaw Nederland B.V. hereby and Macaw Nederland B.V. provides the same in “as is” condition without warranty of any kind, either express or implied, including, without limitation, the implied warranties of merchantability or fitness for a particular purpose. The entire risk arising out of use or performance of the software and documentation remains with you.

    in no event shall Macaw Nederland B.V. be liable for any damages whatsoever (including, without limitation, damages for loss of business profit, business interruption, loss of business information, or any other pecuniary loss) arising out of the use or inability to use the software, even if Macaw Nederland B.V. has been advised of the possibility of such damages. Because some states/jurisdictions do not allow the exclusion or limitation of liability for consequential or incidental damages in certain cases, the above limitation may not apply to you.

    V. MISCELLANEOUS.

    Any disputes arising from and/or related to and/or in connection with the LICENSE AGREEMENT, the formation and/or performance thereof as well as these General Terms and Conditions shall in the first instance be dealt with exclusively by the competent court in Amsterdam. However, the Parties may agree in writing that disputes will be settled by means of arbitration in compliance with the Arbitration Regulations of the Foundation for the Settlement of Automation Disputes (SGOA: Stichting Geschillenoplossing Automatisering) in The Hague.

    The Parties shall not go to court until they have exerted their best efforts to settle a dispute in mutual consultation.

  • SharePoint.DesignFactory.ContentFiles

    Welcome to the landing page of the SharePoint.DesignFactory.ContentFiles NuGet package.

    Please see the following blog posts:

    Documentation SharePoint.DesignFactory.ContentFiles

    About

    The DesignFactory.SharePoint.ContentFiles mechanism is designed for deploying SharePoint files with optional meta data to a SharePoint environment. This SharePoint environment can be:

    • a local environment, running on the same machine as where you are developing or deploying your content files
    • a remote environment, running on either the same machine or a machine that is accessible remotely over http.

    In both scenario's the files will end up in the SharePoint content database, as if they were uploaded by hand. This means that files are deployed in another way than if they were deployed using a WSP package using features and modules. Files are deployed as customized files. See Understanding and Creating Customized and Uncustomized Files in Windows SharePoint Services 3.0 for a good article on customized and uncustomized files.

    Project structure

    A SharePoint.DesignFactory.ContentFiles project has the following strucure:

    • ProjectFolder
      • _MachineConfiguration - configuration files describing connections to SharePoint web (SPWeb)
        • Default.ps1 - configuration file used if there is no specific configuration file for the currenty machine (MACHINE.ps1)
        • Machine1.ps1 - machine specific configuration file
        • Machine2.ps1 - machine specific configuration file
        • SPDesign.ps1 - configuration file for SharePoint web to be used for importing artifacts in project folder if no specific configuration file to use for import is specified [not used yet]
      • _Tools
        • Deploy.cmd - command for deploying all changed files in project
        • Redeploy.cmd - command for deploying all files in project
        • Package.cmd - command for packaging the files in the project
        • Clean.cmd - command to mark all files in the project for redeployment
        • SharePoint.DesignFactory.ContentFiles.ps1 - the script implementing all functionality. Can be called directly as well for more advanced features
        • ContextExtensions... - folder containing extension functions that can be used in ObjectModel and ClientObjectModel
        • Documentation... - folder containing documentation
        • Lib... - folder containing a library of reuseable functions
        • MSBuild... - folder containing a SharePoint.DesignFactory.ContentFiles specific MSBuild targets file
      • MasterPages - A folder mapped in Mappings.xml for deployment to SharePoint
        • MyMaster.master - file to be deployed to SharePoint
        • MyMaster.master.properties.ps1 - metadata for the file to be deployed to SharePoint
        • ...
      • PageLayouts
        • ...
      • ...

    Some remarks on the above project structure:

    • The project structure can be used from any tool that is your favorite HTML editor, like:
      • Visual Studio 2010 (lower versions are supported, but not through nuget package installation)
      • WebMatrix 2.0 (still in beta, does support nuget package installation)
      • ... enter your vaforite web editor here ...
    • Visual Studio 2010 has many enhancements for working with SharePoint.DesignFactory.ContentFiles

    Mappings.xml

    The Mappings.xml file describes a relationship between the project folder and where artifacts in the project folder should be deployed in to SharePoint. The Mappings.xml file looks like:

    <ContentFilesMappings xmlns="http://solutionsfactory.macaw.nl/ContentFilesMappings-1.0">
        <Mappings>
            <Mapping projectFolder="RootFolder" destinationFolder="/" />
            <Mapping projectFolder="Documents" destinationFolder="/documents" />
            <Mapping projectFolder="Masterpages" destinationFolder="/_catalogs/masterpage" />
            <Mapping projectFolder="PageLayouts" destinationFolder="/_catalogs/masterpage" />
            <Mapping projectFolder="Style Library" destinationFolder="/Style Library" />
        </Mappings>
    </ContentFilesMappings>
    

    A Mapping node describes the mapping from a project folder to a SharePoint folder.

    The Mapping node attribute projectFolder':

    • refers to a folder within the project
    • must be specified
    • may not be empty
    • may not point to the root folder of the project, only files from subfolders can be uploaded

    ProjectFolders for multiple Mapping elements must be disjunct; e.g. valid is:

    <Mapping projectFolder="sub1" ... >
    <Mapping projectFolder="sub2" ... >
    

    invalid is:

    <Mapping projectFolder="sub1" ... >
    <Mapping projectFolder="sub1\sub3" ... >
    

    The Mapping node attribute destinationFolder:

    • specifies a folder within SharePoint relative to the SharePointWebUrl as specified in the machine configuration file
    • must be specified
    • may not be empty
    • to specify the root folder in 'SharePointWebUrl' specify '/'

    If the destination folder does not exist yet it will be created as an SPFolder. Any child folders below the projectFolder will result in corresponding child urls (SPFolders) in the destination folder.

    Working with the command-line tools

    The following command-line tools are available for performing the simple tasks involved in working with SharePoint.DesignFactory.ContentFiles:

    • _Tools\deploy [machineconfigurationname] - deploy changed files in the project using configuration MACHINE.ps1, Default.ps1 or specified configuration
    • _Tools\redeploy [machineconfigurationname] - deploy all files in the project using configuration MACHINE.ps1, Default.ps1 or specified configuration
    • _Tools\package - package all files in the project
    • _Tools\clean - mark all files in the project for redeployment

    For more advanced actions like deploying or marking for deployment a single file or folder the underlying PowerShell script _Tools\SharePoint.DesignFactory.ContentFiles.ps1 can be used. To see the available parameters open a PowerShell command prompt in the project foder and execute the following command:

    get-help _Tools\SharePoint.DesignFactory.ContentFiles.ps1

    Open this script file for more details on the available arguments.

    Visual Studio 2010 integration

    There is extensive integration with the Visual Studio 2010 IDE if SharePoint.DesignFactory.ContentFiles is installed as a NuGet package:

    • Create a new ASP.NET 3.5 Web Application project - File -> New -> Project..; Select .NET Framework 3.5; Select template Visual C# -> Web -> ASP.NET Web Application
    • Ensure that the Macaw NuGet repository is accessible:
      • Open Tools -> Library Package Manager -> Package Manager Settings
      • Go to Package Manager -> Package Source
      • Add source: Name = Macaw NuGet, Source = http://nuget.macaw.nl/nuget
    • Add the SharePoint.DesignFactory.ContentFiles NuGet package to the project and solution:
      • Open Tools -> Library Package Manager -> Manage NuGet Packages for Solution...
      • Select Online and the source Macaw NuGet
      • Now select the SharePoint.DesignFactory.ContentFiles package and hit Install. Add the package at both the project and solution level.

    Right click menus

    The SharePoint.DesignFactory.ContentFiles NuGet package adds right click menu entries if the Managed Menu Extension (MME) is installed. These extension can be installed through the Visual Studio 2010 UI:

    1. Open Tools -> Extension Manager..
    2. Select Online
    3. Search for managed Menu Extension (MME)
    4. Select managed Menu Extension (MME) and hit Install

    Close and reopen the Visual Studio 2010 instance containing your project to get the right click menu's loaded.

    The following right click actions are now added:

    On SharePoint.DesignFactory.ContentFiles project:

    • DesignFactory -> Deploy changed files
    • DesignFactory -> Deploy all files
    • DesignFactory -> Mark all files for deploy
    • DesignFactory -> Package
    • DesignFactory -> Documentation ContentFiles

    On mapped folder (folder in project mapped to SharePoint folder with Mappings.xml):

    • DesignFactory -> Deploy changed files in folder
    • DesignFactory -> Deploy all files in folder
    • DesignFactory -> Mark folder for deploy
    • DesignFactory -> Documentation ContentFiles

    On mapped file (file in folder in project that is mapped to SharePoint folder with Mappings.xml): - DesignFactory -> Deploy file - DesignFactory -> Deploy all files in folder - DesignFactory -> Mark file for deploy - DesignFactory -> Documentation ContentFiles

    Configurations

    The SharePoint.DesignFactory.ContentFiles NuGet package adds the following configurations to the project and to the solution, besides the Debug and Release configurations:

    • Deploy: build project in Debug mode, and deploy changed content files
    • Redeploy: build project in Debug mode, and deploy all content files
    • Package: build project in Release mode, and build package

    The following action is also supported when you right-click on a project:

    • Clean: marks all files in the project for redeployment, default project clean action is executed

    Select a configuration and build the project/solution. The configurations correspond with the command-line commands.

    It is also possible to add additional configurations using the Visual Studio Configuration dropdown, with at the end Configuration Manager.... In this way the following additional deployment commands can be added:

    • Deploy machineconfigurationname, i.e. Deploy Office365
    • Redeploy machineconfigurationname, i.e. Redeploy Office365

    Note that a solution configuration builds projects with a specific configuration. This works fine after installation of the NuGet package. If the SharePoint.DesignFactory.ContentFiles package is uninstalled and installed again, the solution configurations are not aligned anymore to the project configurations. To align again open the Configuration dropdown, and select at the end Configuration Manager.... Now align solution configurations with project configurations.

    Machine configuration files

    A machine configuration file is used to describe how to deploy the current project to SharePoint. The machine configuration file describes a deployment to a local machine (SP2007/SP2010) or a remote machine (SP2010). Deployment to the local machine can be done using the ObjectModel or the ClientObjectModel. Deployment to a remote machine is done with the ClientObjectModel. A machine configuration file is:

    • Located in the folder MachineConfiguration in the project folder
    • Named after the machine name, i.e. MYMACHINE.ps1 for the default deployment (Deploy.cmd, Redeploy.cmd) OR
    • Named as wanted. Requires explicit deployment, i.e. Deploy NAME, Redeploy NAME.
    • The machine configuration file Default.ps1 will be used for deployment if no machine specific configuration file exists
    • TODO: The machine configuration file SPDesign.ps1 will be used for importing SharePoint artifacts if no explicit configuration file is specified

    This machine configuration file is executed as a PowerShell script and returns a Hashtable with the following keys:

    • SharePointDeployment - MANDATORY
      • ObjectModel (on server itself, SP2007/SP2010)
      • ClientObjectModel (remote, SP2010)

    If ObjectModel is used for deployment, sharepoint is accessed with the credentials of the current user (integrated security).

    • SharePointWebUrl - MANDATORY
      • Example: 'http://myserver/sites/mysitecollection'

    Url to the SharePoint web site where the content files must be deployed to. In most cases this is the root site of a site collection, but it can be any SharePoint site. The content files in the package can only be deployed to locations within the specified site.

    • UserName - OPTIONAL
      • 'DOMAIN\UserName'

    User name to authenticate with. Must be in the format DOMAIN\UserName. If not specified check if the credentials to authenticate for the SharePointWebUrl are specified in the Windows Credential Manager.

    • Password - OPTIONAL
      • 'MyPassword'

    Password to authenticate with.

    • UseClaims - OPTIONAL
      • $true or $false

    Boolean that specifies if authentication should be done using claims authentication. This is for example the case for Office365. Note that claims-based authentication for now only works with SharePointDeployment set to ClientObjectModel.

    Authentication is done as follows:

    1. If SharePointDeployment is set to ObjectModel
      • Always use integrated security (credentials of currently logged in user)
    2. If SharePointDeployment is set to ClientObjectModel
      • If UserName,Password is specified and not empty, use these
      • Otherwise use the credentials specified in the Windows Credential Manager for Url SharePointWebUrl
    3. If no credentials found --> error.

    Using these key,value pairs multiple authentication approaches can be taken:

    Integrated security:

    @{
        SharePointDeployment = 'ObjectModel';
        SharePointWebUrl = 'http://myserver/sites/mysitecollection';
        UserName = '';
        Password = '';
        UseClaims = $false;
    }
    

    Integrated security (as short as possible):

    @{
        SharePointDeployment = 'ObjectModel';
        SharePointWebUrl = 'http://myserver/sites/mysitecollection';
    }
    

    Explicit authentication (ClientObjectModel deployment only):

    @{
        SharePointDeployment = 'ClientObjectModel';
        SharePointWebUrl = 'http://myserver/sites/mysitecollection';
        UserName = 'DOMAIN\UserName';
        Password = 'Password';
        UseClaims = $false;
    }
    

    Explicit authentication (ClientObjectModel deployment only), but user name and password configured in Windows Credential Manager:

    @{
        SharePointDeployment = 'ClientObjectModel';
        SharePointWebUrl = 'http://myserver/sites/mysitecollection';
        UseClaims = $false;
    }
    

    Explicit claims-based authentication (ClientObjectModel deployment only):

    @{
        SharePointDeployment = 'ClientObjectModel';
        SharePointWebUrl = 'http://myserver/sites/mysitecollection';
        UserName = 'DOMAIN\UserName';
        Password = 'Password';
        UseClaims = $true;
    }
    

    Explicit claims-based authentication (ClientObjectModel deployment only), but user name and password configured in Windows Credential Manager:

    @{
        SharePointDeployment = 'ObjectModel';
        SharePointWebUrl = 'http://myserver/sites/mysitecollection';
        UseClaims = $true;
    }
    

    How files are marked for deployment

    The Archive atribute is used to mark files for deployment. if the Archive attribute is set, the file must be deployed. After a file is successfully deployed the Archive attribute is cleared. The Archive attribute can also be set on read-only files.

    There is a case where the Archive attribute is fooled. If a file that is under TFS source control is reverted to an older version, the file should be deployed again. On Revert the Archive attribute is not set, so the file will not be deployed, although it has been updated (to an older version).

    In case of reverting from TFS source control, mark the specific file or folder for deployment.

    NuGet package installation

    When the NuGet package is installed in Visual studio the following actions are performed:

    • Add the configurations Deploy, Redeploy and Package to the project and to the solution
    • Add import of targets file SharePoint.DesignFactory.ContentFiles.targets in the project file to provide handling of building the configurations Deploy, Redeploy and Package, and a target Package for automating packaging
    • Remove the folders App_Data, Scripts and Default.aspx from the project if it is a web project
    • Copy assembly VSMenuManager.SharePoint.DesignFactory.ContentFiles.dll to the solution folder for right click menu extensions (requires restart of Visual Studio to be picked up)

    This tool is copyright 2012, Macaw.

  • SharePoint 15: What is coming?

    Something everyone busy with SharePoint would like to know: what will be the new features of SharePoint? What has been changed in the existing functionality? A lot of information that will point us in the right direction is available now from the source…

    See the Office 15 Technical Preview - Open Specification Update @ http://blogs.msdn.com/b/officeinteroperability/archive/2012/01/30/office-15-technical-preview-open-specification-update.aspx.

    The material is sometimes hard to read, but there is a lot of information hidden in the documents.

  • PowerShell: script to show detailed information on a set of assemblies

    To get some insight in your assemblies you can use the script below. It gets all information out that I required, but you can extend it if you need for example all assemblies an assembly depends on.

    One thing that was new for we was that I needed functions in a script that can be executed in a pipeline. You can define these functions in the begin {} block.

    Save the following code as Get-AssemblyInformation.ps1. Call for example as follows:

    get-childitem -path "D:\MyProject\tools" -filter '*.dll' -recurse | D:\bin\Get-AssemblyInformation.ps1

    Or if all files are in a folder:

    Get-AssemblyInformation.ps1 –Path "D:\MyProject\tools"

    Get-AssemblyInformation.s1
    1. #requires -version 2.0
    2.  
    3. [CmdletBinding(DefaultParameterSetName="Path")]
    4. param(
    5.    [Parameter(Mandatory=$true,
    6.               Position=0,
    7.               ParameterSetName="Path",
    8.               ValueFromPipeline=$true,
    9.               ValueFromPipelineByPropertyName=$true)]
    10.    [ValidateNotNullOrEmpty()]
    11.    [string[]]
    12.    $Path,
    13.    
    14.    [Alias("PSPath")]
    15.    [Parameter(Mandatory=$true,
    16.               Position=0,
    17.               ParameterSetName="LiteralPath",
    18.               ValueFromPipelineByPropertyName=$true)]
    19.    [ValidateNotNullOrEmpty()]
    20.    [string[]]
    21.    $LiteralPath
    22. )
    23.  
    24. Begin
    25. {
    26.    Set-StrictMode -Version 2.0
    27.     
    28.     function Get-AssemblyCustomProperty
    29.     {
    30.         param
    31.         (
    32.             $assembly,
    33.             $TypeNameLike,
    34.             $Property = $null
    35.         )
    36.         
    37.         $value = $null
    38.         foreach ($attribute in $assembly.GetCustomAttributes($false))
    39.         {
    40.             if ($attribute.GetType().ToString() -like "*$TypeNameLike*")
    41.             {
    42.                 if ($Property -ne $null)
    43.                 {
    44.                     # Select-Object -ExpandProperty fails if property value is $null
    45.                     try {
    46.                         $value = $attribute | Select-Object -ExpandProperty $Property
    47.                     }
    48.                     catch {
    49.                         $value = $null
    50.                     }
    51.                 }
    52.                 else
    53.                 {
    54.                     $value = $attribute
    55.                 }
    56.                 break;
    57.             }
    58.         }
    59.         
    60.         $value
    61.     }
    62.  
    63.     function Get-AssemblyInfoAsHashtable
    64.     {
    65.         param
    66.         (
    67.             [System.Reflection.Assembly]$assembly
    68.         )
    69.         $info = @{}
    70.             
    71.         $info.FullName = $assembly.FullName
    72.         $info.Name = $assembly.ManifestModule.Name
    73.         $info.Location = $assembly.Location
    74.         $info.ImageRuntimeVersion = $assembly.ImageRuntimeVersion
    75.         $info.GlobalAssemblyCache = $assembly.GlobalAssemblyCache
    76.         $info.Title = Get-AssemblyCustomProperty -Assembly $assembly -TypeNameLike 'Title' -Property 'Title'
    77.         $info.Configuration = Get-AssemblyCustomProperty -Assembly $assembly -TypeNameLike 'Configuration' -Property 'Configuration'
    78.         $info.Description = Get-AssemblyCustomProperty -Assembly $assembly -TypeNameLike 'Description' -Property 'Description'
    79.         $info.Company = Get-AssemblyCustomProperty -Assembly $assembly -TypeNameLike 'Company' -Property 'Company'
    80.         $info.Product = Get-AssemblyCustomProperty -Assembly $assembly -TypeNameLike 'Product' -Property 'Product'
    81.         $info.Copyright = Get-AssemblyCustomProperty -Assembly $assembly -TypeNameLike 'Copyright' -Property 'Copyright'
    82.         $info.Trademark = Get-AssemblyCustomProperty -Assembly $assembly -TypeNameLike 'Trademark' -Property 'Trademark'
    83.         $info.DelaySign = Get-AssemblyCustomProperty -Assembly $assembly -TypeNameLike 'DelaySign' -Property 'DelaySign'
    84.         $info.KeyName = Get-AssemblyCustomProperty -Assembly $assembly -TypeNameLike 'KeyName' -Property 'KeyName'
    85.         $info.ClsCompliant = Get-AssemblyCustomProperty -Assembly $assembly -TypeNameLike 'ClsCompliant' -Property 'IsCompliant'
    86.         $info.ComVisible = Get-AssemblyCustomProperty -Assembly $assembly -TypeNameLike 'ComVisible' -Property 'Value'
    87.         $info.IsJITTrackingEnabled = Get-AssemblyCustomProperty -Assembly $assembly -TypeNameLike 'System.Diagnostics.DebuggableAttribute' -Property 'IsJITTrackingEnabled'
    88.         $info.IsJITOptimizerDisabled = Get-AssemblyCustomProperty -Assembly $assembly -TypeNameLike 'System.Diagnostics.DebuggableAttribute' -Property 'IsJITOptimizerDisabled'
    89.         $info.DebuggingFlags = Get-AssemblyCustomProperty -Assembly $assembly -TypeNameLike 'System.Diagnostics.DebuggableAttribute' -Property 'DebuggingFlags'
    90.         $info.CompilationRelaxations = Get-AssemblyCustomProperty -Assembly $assembly -TypeNameLike 'CompilationRelaxations' -Property 'CompilationRelaxations'
    91.         $info.WrapNonExceptionThrows = Get-AssemblyCustomProperty -Assembly $assembly -TypeNameLike 'System.Runtime.CompilerServices.RuntimeCompatibilityAttribute' -Property 'WrapNonExceptionThrows'
    92.  
    93.         $info
    94.     }
    95.  
    96.     function Get-AssemblyInformation
    97.     {
    98.         param
    99.         (
    100.             $AssemblyFile
    101.         )
    102.  
    103.         try
    104.         {
    105.             $assembly = [Reflection.Assembly]::LoadFile($AssemblyFile)
    106.             $info = Get-AssemblyInfoAsHashtable -assembly $assembly
    107.             $info.IsValidDotNetAssembly  = $true
    108.         }
    109.         catch { # it is not a valid dotnet assembly
    110.             $info = @{
    111.                 FullName = $AssemblyFile;
    112.                 Name = Split-Path -Path $AssemblyFile -Leaf;
    113.                 IsValidDotNetAssembly = $false
    114.             }
    115.         }
    116.         
    117.         $info
    118.     }
    119. }
    120.  
    121. Process
    122. {
    123.    if ($psCmdlet.ParameterSetName -eq "Path")
    124.    {
    125.        # In the non-literal case we may need to resolve a wildcarded path
    126.         $resolvedPaths = @()
    127.        foreach ($apath in $Path)
    128.        {
    129.            $resolvedPaths += @(Resolve-Path $apath | Foreach { $_.Path })
    130.        }
    131.    }
    132.    else
    133.    {
    134.        $resolvedPaths = $LiteralPath
    135.    }
    136.    
    137.            
    138.    foreach ($rpath in $resolvedPaths)
    139.    {
    140.        $PathIntrinsics = $ExecutionContext.SessionState.Path
    141.        
    142.        if ($PathIntrinsics.IsProviderQualified($rpath))
    143.        {
    144.            $rpath = $PathIntrinsics.GetUnresolvedProviderPathFromPSPath($rpath)
    145.        }
    146.        
    147.         $assemblyInfo = Get-AssemblyInformation -AssemblyFile $rpath
    148.         Write-Host "***************************************************************************************************"
    149.         Write-Host "**************** $($assemblyInfo.Name)"
    150.         Write-Host "***************************************************************************************************"
    151.         $assemblyInfo
    152.         Write-Host ""
    153.     }
    154. }

    Thanks goes to Keith Hill for some of the more advances parameter stuff which is lent from http://rkeithhill.wordpress.com/2009/01/28/tail-content-%E2%80%93-better-performance-for-grabbing-last-lines-from-large-ascii-log-files/.