npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

clasp-types

v1.4.0

Published

A d.ts generator for clasp projects

Downloads

192

Readme

clasp-types

npm

A TypeScript definitions generator for clasp projects to get autocomplete and type checking for your Google Apps Script Object Oriented Libraries and Client-side API.

Library: library-autocomplete

Client-side API: client-side-api-autocomplete

It works like the API Extractor, reading the @public comment annotations on any global function, class, interface or enum you want to expose, and generating d.ts files consistently.

Features

  • d.ts rollup: Generate a single d.ts from all your .ts files, wrapping global functions into Library interface.

  • Clean library API: Expose only functions and methods through @public annotation, building a cleanner interface and avoiding usage of elements not intended to be exposed.

  • Publish ready: Generate a npm package, with clear setup instructions, ready to be published.

  • Client-side API For Add-ons and Web Apps, generate types for your global functions exposed with @public, in a single d.ts file on @types folder, to get autocomplete for the server API on client.

Here is an example of library types built and published with clasp-types.

Note: clasp-types is intended for generating d.ts from Apps Script code already written in TypeScript. For generating built-in and advanced Apps Script services see https://github.com/grant/google-apps-script-dts

Install

npm i -S clasp-types

or

yarn add --dev clasp-types

Command

clasp-types

Optional params:

--src          <folder>    # default: ./src     - Source folder 
--out          <folder>    # default: ./dist    - Output folder              
--client                   # default: false     - Generate client side API types  
--root         <folder>    # default: ./        - Project root folder  

Library setup

1) Add your library namespace and name to the .clasp.json:

{
  "scriptId": "1B7FSrk5Zi6L1rSxxTDgDEUsPzlukDsi4KGuTMorsTQHhGBzBkMun4iDF",
  "rootDir": "./src",
  "library": {
    "namespace": "gsuitedevs",
    "name": "OAuth2"
  }
}

2) Add @public comment annotation to the code you want to expose

/**
 * Create a service
 * 
 * @public
 */
function createService(serviceName: string) {
  return new Service(serviceName);
}

/**
 * The OAuth service
 * 
 * @public
 */
class Service {
  name: string;
  params_: any;
  constructor(name: string) {
    this.name = name;;
  }

  public getName() {
    return this.name;
  }
  

  /**
   * Sets an additional parameter to use when constructing the authorization URL.
   */
  public setParam(name: string, value: string): Service {
    this.params_[name] = value;
    return this;
  };

}

3) Run clasp-types to generate a npm package with index.d.ts like:

declare namespace gsuitedevs {

    /**
     * The main entry point to interact with OAuth2
     *
     * Script ID: **1B7FSrk5Zi6L1rSxxTDgDEUsPzlukDsi4KGuTMorsTQHhGBzBkMun4iDF**
     */
    export interface OAuth2 {

        /**
         * Create a service
         */
        createService(serviceName: string): Service;

    }

    /**
     * The OAuth service
     */
    export interface Service {

        getName(): string;

        /**
         * Sets an additional parameter to use when constructing the authorization URL.
         */
        setParam(name: string, value: string): Service;

    }

}

declare var OAuth2: gsuitedevs.OAuth2;

Notes:

  • On classes annotaded with @public, methods inside then should also be marked as public in order to be exposed. Private or protected methods will not be exposed.
  • Interfaces and Enumerations with @public annotation will have all members exposed by default.

A npm ready to publish package is generated in the output folder, with some setup instructions on README.md, so you can easily share your library types. Here is an example.

Suggestion: You may add a dist-tag to your types package distribution with the same version of the script, say, v23, so users can link the types version with script version, and use ones that matches.

Dependencies

If your package expose a transitive dependency on params or return types, such as GoogleAppsScript.HTML.HtmlOutput from @types/google-apps-script, add it to "dependencies" section of your package.json, instead of "devDependencies":

  "dependencies": {
    "@types/google-apps-script": "^0.0.59"
  }

So, clasp-types will correctly setup the reference on index.d.ts:

/// <reference types="google-apps-script" />

And on the resulted package.json:

  "dependencies": {
    "@types/google-apps-script": "*"
  },

Client-side API setup

1) Add @public comment annotation to the code you want to expose to client

/**
 * Execute a sum on server side, from client side
 * 
 * @public
 */
function sumOnServer(a: number, b: number): number {
  return a + b;
}

2) Run clasp-types --client to generate a index.d.ts like:

declare namespace google {

    namespace script {

        export interface Runner {

            withSuccessHandler(handler: Function): Runner;

            withFailureHandler(handler: (error: Error) => void): Runner;

            withUserObject(object: any): Runner;

            sumOnServer(a: number, b: number): void //number;
            ...

        }

        export var run: Runner;

    }
    ...

}

TypeScript on Client-side

To develop with TypeScript on client side, you should work with separated ts files and inline the corresponding js, as well as all css in the same page, in order to the resulting html template be processed by the HTML Service.

To perform the inlining a great tool is the inline-source-cli, so you can add a inline tag to your js and css references:

<head>
  ...
  <link inline href="page-style.css" rel="stylesheet">
</head>
<body>
  ...
  <script inline src="page-activity.js"></script>
  <script inline src="page-view.js"></script>
</body>

And then use a tool such as glob-exec to inline all your sources in one single script line:

glob-exec --foreach './build/**/*.html' --  'cat {{file}} | inline-source --root build > dist/{{file.name}}{{file.ext}}'

Background

The clasp-types was originally created as a foundation for the BkperApp library and the Bkper Add-on for Google Sheets, with inspirations on the API Extractor, DefinitelyTyped and previous work from grant, motemen and mtgto - thank you guys :-)

Libraries are a great way to share code between scripts, but, once published and others start using it, it requires some level of care like any other public API, so, applying some API Extractor concepts and principles help to keep the quality of the Library and avoid accidental breaks.

DefinitelyTyped is an amazing initiative and works really well for publishing types for thirdy-party libraries written in js, as well as for the Google Apps Script built-in and advanced services, although, as its recommended in the official declaration publishing documentation, for libraries written in TypeScript, build its own npm package is favored, and give some advantages:

  • Instant publishing
  • Release automation
  • Dist-tag for mapping script versions

The down side is that it requires one aditional aditional types configuration step, so, clasp-types automatically generate a package ready to publish, with instructions on README for scoped packages to setup the typeRoots and non scoped packages to setup the types.

Help welcome