TypeScript and SharePoint - definition files

 

One of TypeScript's strengths is that you can use the ability to define Interfaces to produce Type Definition files for JavaScript.  These interface definitions provides an IDE (like Visual Studio) with a lot more type information at compile time regarding how to use a certain JavaScript object.

A large repository of definition files are at: https://github.com/borisyankov/DefinitelyTyped

Why is this related to SharePoint?  Well, javascript files provided in SharePoint are actually quite rich in meta data and could potentially be used to reverse engineer the TypeScript Definition Files. 

Without further delay...

  • Here's my TypeScript program
  • which will generate a JavaScript program
  • which will parse and read SP's JavaScript objects
  • which will produce TypeScript definition results

 

TypeScript code

 

module tools {

    export function findReturnType(o: any): string {

        // return;
        if (/return\s*;/gi.test(o)) return ": void";

        // no return
        if (!/return/gi.test(o)) return ": void";

        // return 1.1; return 1;
        if (/return\s*\d+(\.\d+)?;/gi.test(o)) return ": number";

        // return "xx";
        if (/return\s*"[^"]*?"\s*;/gi.test(o)) return ": string";

        // return 'xx';
        if (/return\s*'[^']*?'\s*;/gi.test(o)) return ": string";

        // return something;
        if (/return\s*[^;]+?;/gi.test(o)) return ": any";

        // don't know
        return ": any";
    }

    export function toClass(o: any): string {
        var isClass = o["__class"] == true;
        var typeName = o["__typeName"];

        var results = "interface " + typeName + "{\n";

        for (var member in o) {

            if (member.match(/\$|__/)) continue;

            var m = o[member];
            if (typeof (m) == "function") {
                var match = /function\s*(\(.*?\))/gi.exec(m);
                if (match) {
                    results += "function " + member + match[1] + findReturnType(m) + ";\n";
                }
            }
            else {
                results += "" + member + " : " + typeof (m) + ";\n";
            }
        }

        results += "}\n";

        return results;

    }

    export function toEnum(o: any): string {

        var typeName = o["__typeName"];
        var results = "interface " + typeName + "{\n";

        for (var member in o) {

            if (member.match(/\$|__/)) continue;

            var m = o[member];
            if (typeof (m) == "function") {
                continue;
            }
            else {
                results += "" + member + " : " + typeof (m) + ";\n";
            }
        }

        results += "}\n";
        return results;
    }

    export function toTypeScript(o: any): string {
        var isClass = o["__class"] == true;
        var isNamespace = o["__namespace"] == true;
        var isEnum = o["__enum"] == true;

        if (isClass) {
            return toClass(o);
        }
        if (isEnum) {
            return toEnum(o);
        }
        return "";
    }
}

 

What does this do?

 

When you run this code in the SharePoint browser console, you'd get this:

image

Which is nearly a usable TypeScript definition file. 

There are still a bunch of clean up to do, since this is a really basic list:

  • You will need to clean up the interface name. 
  • If you want, improve the arguments list, a number of the arguments are actually optional.
  • Remove zIndexStep and zIndexStart - which are properties in SP.UI.ModalDialog but aren't for public use.
  • Remove bind function - that's from jQuery

 

Here's another example, with enum's defined in SP.UI

image

 

Summary

In this quick blog article, I talked about using a TypeScript program to read the javascript object, and infer TypeScript definitions.  Since TypeScript contains far more information that isn't available in JavaScript, there will still be need to manually tweak the output.

Eventually, I hope we'll arrive at a place where we have fully documented TypeScript definitions for SharePoint available. 

Charlie Holland has started such a work, and it is available on https://github.com/chaholl/TypeScriptDefinitions/

http://www.chaholl.com/archive/2013/02/18/a-collection-of-typescript-definition-files-for-sharepoint-2013-et-al.aspx

Example uses of SPServices, JavaScript and SharePoint

 

I wanted to write about spservices.codeplex.com from Marc D Anderson - we've found ourselves using this really special library time and again across different projects to talk back to SharePoint quickly.

 

Starting Workflows

Here's a page from one of our Process Wiki articles.

image

 

  • We have a special "Contributor-only" webpart on the right. 
  • It shows the various workflow status' on the current page, as traffic light bubbles. 
  • The "Certify Process Page" calls a javascript function that calls StartWorkflow via SPServices.
  • The workflow is a Nintex workflow and triggers a significant multi-stage approval process.  But you can use StartWorkflow to start SharePoint workflows as well.

 

Getting List data, lots of list data

Here's our task list, represented as a taskboard.

image

  • This one is completely done with SPServices to get the list items
  • Convert the objects to JSON using SPServices.SPXmlToJson
  • Then binding the objects to UI via KnockoutJS
  • There's JQuery UI's drag and drop in play, so we can change the Task's status by dragging the task across a different column.
  • Update task using SPServices' UpdateItem call.
  • And some nice CSS. 
  • This particular page also runs via SharePoint 2010's OData listdata.svc, but is completely viable with SPServices on SP2007 as well.

 

Getting User Profiles via Search

Here's our People page.

image

 

  • First, get SharePoint to index your people.
  • Use SPServices to call SharePoint search to return a bunch of people, including their picture (one would say, especially their picture).
  • Here I use Knockout to render the pictures.  When clicked, each one opens that user's My Site page.
  • There's a filter box on the top right, as well as "fake" refinements on the left hand side that allows us to re-query SharePoint search for filtered people.
  • One possible idea here would be to use SPServices' User Profile Service support and talk directly to the User Profile service, if you want to skip the search service.

 

Summary

A quick post of 3 recent javascript customizations that heavily used SPServices.  Hope that give you guys a lot of ideas.  Let me know what you guys think.

Nintex Workflow - using all Regex options in your actions

 

Nintex Workflows supports a Regular Expression action.  This action has a very simple configurable UI with only the "Ignore case" option.

But there are a number of other very interesting Regex Options that you may want to use in your pattern.  This blog article is about how to enable them, and what sort of patterns you might use them for.

 

Regular Expression Options

Making an educated guess that the Nintex workflows uses the standard .NET Regular Expression (System.Text.RegularExpressions.Regex) rather than implementing their own regex engine.  Here's a list of the Regular Expression Options supported in the .NET Framework.

http://msdn.microsoft.com/en-us/library/yd1hzczs.aspx

  • i = IgnoreCase (this option is available in the Nintex action)
  • m = Multiline, if enabled, ^ and $ matches beginning and end of each line, rather than the whole block of text
  • s = Singleline, if enabled, . (period) matches all characters including newline (\n), by default, the period character only matches [^\n] (any character except the newline).
  • n = ExplicitCapture, don't capture groups
  • x = IgnorePatternWhitespace, ignore unescaped whitespace, and allow inline # comments

 

Using Regex Options within a pattern group

.NET allows you to use regular expressions with special options within a pattern group.  To do this, the pattern is:

  • (?imnsx-imnsx:pattern)

You can read up about it here: http://msdn.microsoft.com/en-us/library/bs2twtah.aspx#group_options

Lets see some examples.

 

Using the multiline option

Example, given this block of text:

Dear John,

Thanks for the email.

/footer

We want to extract the line that has the word "thanks".

We can use this expression:

  • (?m:^.*thanks.*$)
  • multiline match of any line that contains the word thanks.  Match from beginning of line ^ to end of line $.

image

The results in the workflow:

image

 

Using the singleline option

Example, given this block of text:

Dear John,

Thanks for the email.

/footer

We want to capture everything before the /footer.

  • ^(?s:.*)(?=/footer)
  • use singleline option, match any character (including line breaks).  Use a positive look-ahead match on /footer, but don't actually include it in the pattern match result.

image

The results in the workflow:

image

SharePoint Saturday Sydney 2012

Thank you all for attending SharePoint Saturday, giving up your time.  Sydney marks the last of the 6 SharePoint Saturdays that I've had the privilege to present in this year, ticking off:

The best part of SharePoint Saturday is just meeting talking to the enthusiastic SharePoint fans and hear what people are doing out there.  Honestly, not many people are that crazy to give up a sunny Saturday to learn about SharePoint - you guys are amazing.

The worst part is the travel. 

 

Sydney SharePoint User Group

I was honestly surprised almost everybody already know about the Sydney SharePoint User Group.  We meet monthly in the CBD between 6-7pm on the 3rd Tuesday of the Month.  We actually start at 5:30pm to eat up all the pizza first, and for the guys that don't need to head home right away, join us at the pub and geek out.

Sign up here so you can see what topic is coming up next month:

 

Golf Course

The User Group gave away a Miniature Golf Course during the event.

The Miniature Book of Miniature Golf

If you didn't manage to win one, but is still interested in it, it's here:

 

Downloads

SharePoint Saturday Canberra 2012

I had the pleasure of presenting REST services and AJAX at Canberra again.  It was a fun and sunny day that started at 4am in the morning, and packing a sleeping mr4 into the car and drive down.  Mr4 and my wife went to see the Cockington Miniature Gardens for the day, leaving me to geek out with fellow crazy SharePoint Saturday-ers.

As promised, there are a number of links:

 

Some of the comparisons I've made in the talk:

  • In SharePoint 2013, Microsoft wants you to use the services to talk to SharePoint, either via the Client Object Model, or via JavaScript and REST.  They also provide a whole lot of service endpoints for you to use:
    • /_vti_bin/listdata.svc
    • /_vti_bin/*.asmx
    • /_api/
  • In SharePoint 2010, you don't have nearly as many service end points, nor all the capabilities, but you can build custom services (which BTW, will still work in 2013).  So if you want to future-proof your solutions it is good to start thinking about implementing services and keeping the Javascript UI tier separate from the underlying services.
  • In the SharePoint 2013 Azure Workflow model, you can't deploy workflow actions.  But you are given an out of the box action that will let you call web services.  So building custom services is still a good way going forward to implement functionality that you can then reuse.
  • Re-use everywhere:
    • InfoPath
    • Workflow Web Request action
    • JavaScript AJAX